#archived-code-advanced
1 messages · Page 137 of 1
I don't understand
in my case I am spawning particles
vision of around 20 tiles should cover the screen
Okay, do all you do is spawn a particle in every square that isn't visible
And you have to detect which are visible
The particles thing isn't really relevant
No, raycasting to all tiles too expensive
So just do the perimeter?
I cast from all walls and spawn particles at the points
leaves holes
I don't know what the particles are
1x1 squares
But what do particles have to do with fov?
Oh, I get it!
Yep I understand
So yeah, forget that approach, it's inherently flawed
What you want is to have a grid of all tiles, and know which are visible
Once you have that you can spawn a particle on every tile that is invisible
That's fairly straight forward
Cast from player to walls all points = visible and fill rest?
In my game (which is not tile based) I do 120 casts every frame
Radially
And that's enough
For my particular thing
You could say... cast to every tile in a ring around the player that is of radius 10
triangles?
Draw a line around the edge, connecting the point of each ray
The area contained is your vision
And then what?
Then spawn particles on every square that is not within that area
It's a bit involved
I would research roguelike tutorials, I'm not sure that my method translates to a grid perfectly
I'm gonna look around in reddit post u sent
ok
There is also a roguelike dev discord that's pretty good
oh god
Yeah it's hectic
It's a tough problem
I swear I've seen this method explained in a way that seemed simple, but it was ages ago
There is the page of techniques
You could probably find YouTube videos on it
Gtg, good luck
You can make a mesh of all your walls … extrude them very high. Make them render black… Put a camera directly above your player, looking at it… this camera will then render a mask of your LOS…. Check Ape out or teleglitch for how it looks… this is effectively shadow casting… but through a special case of perspective projection that is almost free
You can also render to a render texture and map the pixels to your tiles… you can then even compose multiple such RTs to have multiple ‘eyes’ eg to reveal stuff temporarily etc.
Hello, i have rig builder that have many rigs in layers but all layers are inactive. Why rigbuilder affect my animations even when there is no layer active? animations are speeded up and sometimes (like every 3 seconds) break and for few frames it looks like every bone is twisted. When i disable rigbuilder in runtime everything looks fine
what?
I can not find the problem...
(29,34): error CS1002: ; expected
but I do not know what is the problem, I know ";" but where...
i think you are missing your opening { after that second IF
and maybe a closing one? basically it thinks you need a ; because it's confused about how many blocks you have there
Maybe it's the capital I?
look "(27,34): error CS1002: ; expected"
Lots of basic syntax errors here. #💻┃code-beginner will give you better help with this kind of issue
Okay
No, it’ll just pick first one.
Using MLAPI, I need to take hosts mapseed INT and give to client before he loads game, how do I do this?
Maybe call an RPC and if host, then for each client give the mapseed? then load game.
Yeah you'll need to use an RPC for this
ok, thank you 🙂
What is the damn shortcut for changing a method name throughout a script?
Try and stick to one channel, rather than three
I thought there was a way to select all the same text in a script then as you typed/edit it changed them all at once
if you are using visual studio, after changing a method name, there should be a wrench icon next to the line number
I already replied to you in the other thread
That did not work
that's why crossposting is not allowed
does anyone know if there is any way to get a reference to a Function, or MonoBehaviour, or something; so that I can have different abilities per character? I am storing my character's stats in Scriptable Objects and want to have different abilities per character. I'm using a script inheritance/override system for each characters abilities;
public class AssaultRecruit : OperativeBase
{
public override void Ability()
{
return;
}
}
I'm not sure how I'd call the Ability from the player either, to be fair.
Ideally, i'd be able to set the function like you can with the OnClick section or OnUpdate function of a slider
have you seen this tutorial? https://learn.unity.com/tutorial/create-an-ability-system-with-scriptable-objects#
cheers 🙂
I want to execute some code on a separate thread but it's a situation where more work might be triggered and I want it to execute right after the initial work so they are executed in order, it's doesn't all have to be in the separate threads but it does need to be in a separate thread from main and execute in order
I looked at Join(), but I'm a bit confused how to sync them up if the first thread finished already
Jobs might have more of this kind of control flow built in
I'm really not sure how to implement this with jobs since it's not touching unity at all
What does it touch then?
As far as i see jobs are about updating unity components
it's just generating data
Not really, they're actually the opposite
Jobs are just generating data.
Wether you apply it to components later on is up to you.
hmm okay then i misunderstood how jobs work, i'll look further into it
does anyone have good examples of the job system for generating some data with multiple jobs?
..what kind of data?
well in the end it's basically this Dictionary
new Dictionary<string, Dictionary<int, List<Vector2>>>();
What is it actually? I don't have a lot of experience with jobs but I doubt you'd be able to generate and populate such a complex data type without banging some heads
the data is already being generated and being populated but assigning it can take a long time, so i have to schedule it all somehow, the list contains collision paths to be assigned to a Polygon Collider 2D
so it has to be something like
Generate Collider data 1
Generate Collider data 2
if both done then assign collider data to Polygon Collider 2D
if not then wait for all Generation to finish and then assign the data
looks like this
basically every time you place a block all collision is recalculated for that chunk and then assigned to the polygon collider 2d for that chunk
i don't know the fix to this problem but another solution (that might not require as much resources) would be to use a composite collider on many small box colliders, since you're only placing boxes and then joining them together
yeah, at first i tried just placing box colliders on every block, but this gets insanely slow when spawning thousands of box colliders for each chunk
1000000x slower
it literally took minutes to generate and assign all the collider data where as this takes 10 miliseconds
oh ok
why not do them both sequentially in just one new thread?
well yeah, that's my intention, but I need to figure out how to sync them up, because one generation might be triggered and finish in which case a new thread gets started, if one exists then the new one will have to join the existing thread and so on..
you never do threading like that. if you have a work that you know for which you need a dedicated thread throughout the applications lifetime then you simply spawn a thread at the beginning and then maintain the same thread till end.
make thread do work using signalling, interlocks, whatever you feel comfortable with
spawning a new thread is very expensive and a new thread is not at all faster than the main thread unless you're using the other thread for I/O in which cpu is mostly idle or is waiting for signals from some other hardware
hmm, how do you maintain and reuse the same thread? do i just instantiate one and reuse it, possibly joining the new threads to it somehow? 🤔
or just start more work on the same thread? 🤔
static AutoResetEvent as = new AutoResetEvent();
static bool isRunning = true;
void Awake()
{
new Thread(DoWork).Start() ;
}
static void DoWork()
{
while(isRunning)
{
as.WaitOne();
if(isRunning)
Debug.Log("Print from thread");
}
}
void Update()
{
if(Input.GetKeyDown(KeyCode.K)) as.Set();
}
void OnApplicationQuit() //gracefully end the thread when application is trying to quit
{
isRunning = false;
as.Set();
}
written from mobile, there maybe some syntax issues but you get the basic idea of it
not sure what you're doing with the AutoResetEvent, but i think I get the basic gist of it, you're just keeping it alive with a while loop and using that loop to poll for work
AutoResetEvent is used for signalling. Until you call Set function your thread is blocked at that line
There's an alternative ManualResetEvent which does similar work but has some difference in how the signalling works. Read more about it from ms docs
okay, that makes sense, ty
why not use async ... await for synchronization and combinations of await Task.WhenAny(a, b, c) and await Task.WhenAll(a, b, c) to join. Threads will be created on the thread pool and thread reuse is no issue... you can create a simple main thread callback by pushing callback actions into a ConcurrentQueue<Action> and popping items off in Update().... using signalling primitives is usually much more prone to concurrency bugs that that are a PITA to debug. Depending on your use case, i.e. if you want performance (full IA level optimization)... IJob is the only real ticket and I wouldn't bother with C# stuff for anything but scheduling & sync.
I want to generate a direction vector that points to a random point on a (northern) hemisphere around a point. I could do a random vector like x(-1,1) y(0,1) and z(-1,1) but I'm worried it won't produce an equal spread. And I don't really know how to figure it out. Is there anyone who knows a good way?
Why I try to reference an action this way it is returning null. Any ideas what I am doing wrong here? ```
public enum EffectID
{
none,
damage,
changeSTR,
healByPercent,
healByValue
}
public class EffectDB
{
public static Dictionary<EffectID, Action<Effect, Character>> effects =
new Dictionary<EffectID, Action<Effect, Character>>()
{
{EffectID.none, None},
{EffectID.damage, Damage},
{EffectID.changeSTR, ChangeSTR},
{EffectID.healByPercent, HealByPercent},
{EffectID.healByValue, HealByValue},
};
private static Action<Effect, Character> None = (effect, character) =>
{
return;
};
private static Action<Effect, Character> Damage = (effect, character) =>
{
float value = Mathf.Floor(effect.Power * UnityEngine.Random.Range(.8f, 1f));
value += Mathf.Floor(value * (GameData.source.GetDerivedStat(effect.Base.scalingType) * .1f));
value = character.CheckProtection(value, effect.Base.damageType);
if (value != 0)
{
if(effect.Base.hideInUI)
{
GameEvents.OnGenerateDialog(DialogType.combat,
$"{GameData.source.CharacterName} dealt " +
$"{value} {effect.Base.damageType} damage to {character.CharacterName}.");
}
else
{
GameEvents.OnGenerateDialog(DialogType.combat,
$"{effect.Base.effectName} dealt " +
$"{value} {effect.Base.damageType} damage to {character.CharacterName}.");
}
character.ChangeHP(-value);
}
};```
Vector3 sphere = Random.insideUnitSphere;
Vector3 hemisphere = new Vector3(sphere.x, Mathf.Clamp01(sphere.y), sphere.z);```
if I just declare them like this in the dictionary instead of referencing an action they work though ()=>
changing the variables to public changes nothing.
Thanks! I should have said I'm doing it in VFX graph but I think this is actually enough. I'll try it!
You don't actually need to do this:private static Action<Effect, Character> None = (effect, character) => { return; };
You can just do this:
{
return;
}```
Just a normal method.
I'm asking this again since I don't know how to do it
I have a class that holds a item scriptable object, an int for the amount of that item, and a string
I wanna be able to save these with a binary formatter
you can't serialize scriptable objects tho
and people say I should make an item database
but I don't know how to make that work with the class I mentioned before
Hmm, I'm not familiar with any of these, if you have any usage examples it would be appreciated
public class ItemSlot
{
public Item item;
public int amount;
public string scene;
}```
should I just somehow save the id of an item and then save the int and string separately?
public class ItemSlot
{
public int itemId;
public int amount;
public string scene;
}```
like so?
for each scriptable object for an item, assign it either an int or a string as an identifier, then have a dictionary of type <int, Item>
then yeah do that class it would be able to be serialized
and then I can just get the id from a database using that int
I'm using this during runtime tho
so I would have to get the item id a lot
is that performant?
you can do it once in Awake and make another class that has Item instead of int
then pass it in this serializable class to construct from
in your ItemSlot class, have a constructor like
void ItemSlot(SerializableItemSlot data)
{
item = database[data.itemInt];
amount = data.amount;
scene = data.scene;
}
alright!
then call that in Awake like
ItemSlot thisSlot = new ItemSlot(theSerializableItem)
database would be the name of your dictionary
and your itemInt is what you called the int that stored the id in the serializable class
how would I make the database
I've never had to make them
can I make a scriptable object a singleton?
that's what I did
I'm still getting an error on ItemSlot
https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=net-5.0
this is how you make a dictionary, the key would be int and the value would be a scriptable object
generally scriptable objects purpose is to have multiple of them created, it would be better to make a normal static class
ok but why am I getting an error on ItemSlot
i told you, database isn't defined you need to make a dictionary for it
and i don't know what you've named your itemId in your serializable class
ok I get that but like, how do I make the database
how do I make it so I can just drag in all the items in the editor
it has a dictionary and everything
but idk what it should be
you'd need a serializable dictionary which can appear in the editor
i don't know of any off the top of my head but you can search for one
or you can have normal SO fields and list out the dictionary manually
using UnityEngine;
[CreateAssetMenu(fileName = "New Item Database", menuName = "Inventory/Item Database")]
public class ItemDatabase : ScriptableObject, ISerializationCallbackReceiver
{
public Item[] items;
public Dictionary<Item, int> GetId = new Dictionary<Item, int>();
public void OnBeforeSerialize()
{
GetId = new Dictionary<Item, int>();
for (int i = 0; i < items.Length; i++)
{
GetId.Add(items[i], i);
}
}
public void OnAfterDeserialize()
{
}
}
I found this online
I could just make the dictionary serializedDictionary but yeah
I was thinking of having something like this
an array?
yeah then refer to the items with their index
so I don't need a dictionary then?
later on I could probably make it get all the items from the resources folder
if you want to refer to only refer to them by index then you don't need it no
I know
that's all I need
but I still don't understand why this is marked as an error
what does the error say?
oh sorry i forgot u don't need the void
Inventory.ItemSlot itemSlot = new Inventory.ItemSlot(new Inventory.SerializableItemSlot { itemId = ItemDatabase.instance.GetId[itemSlotToDrop.item], amount = 1, scene = SceneManager.GetActiveScene().name });
well that just turned into a monstrosity
yes, I know
and now if I wanna save them?
do I give the serializable item slot class?
Q: How can I check system processes from android build while on emulator?
yes
and when I wanna load the data?
cause now they're different types
I wanna set the list of items be equal to the list of serializable items
you make a new ItemSlot with the argument of the serializable class
yes but not making a new serializable class but loading it from data
you would load the serializable class
then pass it into the ItemSlot constructor
yeah
well test it out
it looks fine to me you just don't need the GetId dictionary anymore
what are you using that for
uhhh
this
here I wanna add a new item with the amount of just one
Constructor 'ItemSlot' has 1 parameter(s) but is invoked with 0 argument(s)
you need brackets?
after you initialize, you can set what the amount is
or you can make another constructor for ItemSlot
//not real code
ItemSlot(Serializable data, int overrideAmount)
{
//same as before
amount = overrideAmount;
}
yeah that works as well
and you don't need to do item = ... if your arguments are in the same order as in the constructor
what does it say
one is itemslot and other is serializableitemslot
then change the type?
of savedata's itemList
or is it that you need to serialize the data
this constructor gets the data from a monobehaviour of playerdata
and it takes that in as data to save
itemList.indexOf()
to get the itemId
and i think you need to make a constructor for serializable data?
how do I write that line
like for the non serializable but the other way round
uhh
I just need to convert the serializable data to non serializable
like, make it equal to
is itemList the same as ItemDatabase.instance.items?
because if not then the index you passed in won't refer to the right index of the database list
it's an array of items
so no
itemList is a list of itemSlots
I also have class, can we wait 10 - 20 minutes or so?
you'd want to do Array.IndexOf(temDatabase.instance.items, itemList[i])
to get the index of that item
sure just ping me
@frail dock Did you manage to solve your issue?
sorry i'm not at home
won't be for a few hours
Question
what is known about private variable initialization in a MB?
For example string s; is not null, which means it's not default(string). So Is it documented somewhere how they are initialized?
(If have resources, e.g. documentation please mention me)
yeah, got a couple of solutions, also apparently since it's just a few ms execution I can actually run the generation on main thread and just use an IEnumerator to assign the colliders
sure i'll message you when i can
aight!
So you gave up on multithreading? I was kind curious since I might be using jobs or threads for my current project in the future.
ahh no, i still have a lot of things i have to use it for haha, such as chunk loading, possibly ai pathing, map scanning and other stuff
if you look up people posted a couple of solutions
Okay. So I think the workflow of jobifying something is to define the algorithm first. Something that you do in 1 function. Then see how you can turn everything from references to just data processing. Maybe picking data from 1 or several arrays and processing it with a certain algorithm. Then saving the result in another array. The result array is then used on the main thread for whatever you want.
Yeah I've seen them. All of them seem interesting, so I'll be curious to have a look at whatever solution you decide to use(if any).😅
hmm, well in my current scenario i made an algo to calculate the exposed faces and points around them for collision data, it's just a few loops finding out target blocks and scanning around them, i assumed that the scanning around them would take a long time since a chunk has 10000 blocks but it only takes around 8ms so i can actually just run that in the main thread without seeing hangups, i'm only seeing hangups when the paths are actually allocated to the Polygon colliders 2d
8s is still considerable time. Does the hangup happen on the physics side?
look at that baby go 😄
Nice
it is, but no noticable lag ingame from this
you can see the execution times there
last step is s4 which is assignment
that's what takes the most time the more and more paths get added
each single block or holes or separated blocks need their own path..
so you can end up with 100 paths.. which makes the assignment take 100-300ms
By assignment you mean what? Can I have a look at that part of code?
it's just this
foreach (var each in collisionPathsList2) {
PolygonCollider2D pc2D = colliderPairs[each.Key];
pc2D.pathCount = each.Value.Count;
var counter = 0;
text.text = "UPDATING CHUNK " + each.Key;
foreach (var each2 in each.Value) {
pc2D.SetPath(each2.Key, each2.Value);
if (counter % 5 == 0) {
yield return null;
}
counter++;
}
}
yield every 5 seems to remove any hangups
but i'm getting index out of bounds, possibly cause it's executing out of order, so i'll have to think of something about that
Can't each block just have a square collider?
unfortunately not, it's a million times slower to do that since you're dealing with potentially 10.000 - 30.000 unity objects and a lot more on map generation
Ty 👍
I dont understand
have you googled "teleglitch" and watched a gameplay video? Should be obvious what i mean with that visual reference.
but the los in teleglitch is a smooth one
doesn't matter, same principle applies
it doesn't even have to be a visible renderer... its just a way to compute LOS with a camera projection and stuff that is very fast/optimized in unity...
what is a camera projection and stuff?
In computer vision a camera matrix or (camera) projection matrix is a
3
×
4
{\displaystyle 3\times 4}
matrix which describes the mapping of a pinhole camera from 3D points in the world to 2D points in an image.
Let
x
{\displayst...
summary: you can solve LOS by rasterization of occlusion meshes instead of raycasting
related application is in the idea of https://en.wikipedia.org/wiki/Shadow_volume
Shadow volume is a technique used in 3D computer graphics to add shadows to a rendered scene. They were first proposed by Frank Crow in 1977 as the geometry describing the 3D shape of the region occluded from a light source. A shadow volume divides the virtual world in two: areas that are in shadow and areas that are not.
The stencil buffer impl...
sometimes 2D problems can be solved more easily by adding a 3rd dimension....
but I dont understand what it is or how it works
can't help you with that i'm afraid... takes some reading i guess
what i described yesterday is the most straight forward way to do it without any special 3D-math knowledge
i.e. camera above the player, looking down with walls extruded high as occluders/pseudo-shadow-volumes
kinda funny that hardly anyone uses that trick... its so elegant
make mesh that covers all walls
making it an occluder so things behind it dont get rendered?
How about having your stats and effects as scriptable objects. So you can have a base effect SO and many different types of child effects, like ModifyStatEffect and RestoreStatEffect. Then you can even combine them in a CombinationEffect that would run both of the effects immediately/in order, etc... The Stat SO would hold a list of all the current effects, an unmodified value and a property that returns modified value. The effects will handle adding and removing themselves to the Stat effects list.
things like movement speed are contained in a "movement" component that's attached to anything that can move.
Everything that can move? like, non character objects too(cars or rolling stones)? Do you want your effects to affect these objects too?
The benefit of an SO is indeed the fact that you can create many instances in the inspector and configure them the way you want. With what I mentioned, you can have one CombineEffect and one ModifyStatEffect SOs and make hundreds of combinations just with these by just creating new instances and dragging the references around + setting some numbers. No need for a separate class for each stat or creating(hardcoding) thing in code. It's also easier to reference them from anywhere in your project as opposed to regular or Mono classes.
Regarding the first issue, you could either have a special class that would contain stats of the object, or make your classes, like "movement" implement some kind of interface that would return a list of stats.
scriptableobject that's editable in inspector, with effects like
ModifyMovementSpeed, EnableBleeding, TeleportRandomly, GiveItem, ReduceArmor, InstantiateObject and anyone could add these effects through inspector but wouldn't that be limiting for what the effect can do?
It will not be limiting, because you will write generic effects and configure them in inspector for whatever effect you want. For example, ModifyMovementSpeed would be ModifyStat instead, and you'll be able to set any kind of stat, like movement speed. EnableBleeding would be ModifyStatOverTime following the same logic as the previous one. Could even make it ApplyEffectOverTimeEffect and plug the ModifyStatEffect that reduces Health stat into it. It's super configurable and extendable.
can I use a variable in it, that I replace where I call it?
if you know what I mean
Depends on the context. You can use captured variables in the expression itself (inside the curly braces). The only time I ever passed anything in the parenthesis is in Linq functions.
Ah, I guess if you use it as a delegate, the stuff in parenthesis has to match the delegate parameters.
so I can add parameters to functions that are parameters?
Not sure what you mean. You can use variables from the current scope right inside the anonymous function.
int uselessInt = 0;
someEvent += () => {uselessInt += 1;};
Something like this.
A = new A( ()=> { ABC.GetComponent<SpriteRenderer>().sprite = null; } )
public class A
{
GameObject Asigned;
public A(Func function)
{
// call function but replace "ABC" with "Asigned"
}
}
how do I do this?
while (!assedUnload.isDone)
yield return null;```
Anyone can explain to me why right after this memory is still occupied, but if i wait a little bit longer it actually gets freed?
I want to use the variables that are on the other side
A = new A( go => go.GetComponent<SpriteRenderer>() ... );
public A(Action<GameObject> function) { f(Asigned); }
So, basically, in () => { ... } you can replace the () with a single argument, or with (arg1, arg2, etc.)
Oh?
And then, where you want to take the function in (the A constructor in this case), you need to declare what kind of function you want, i.e. what arguments it takes and what it returns
You can use predefined types like Action<T>, Action<T1, T2> etc. (or Func<T, TReturn> etc.) or declare your own such type using the delegate keyword
new A( c => { c.GetComponent<SpriteRenderer>().sprite = null; } )
public class A
{
GameObject Asigned;
public A(Action<GameObject> function)
{
f(Asigned);
}
}
so this works?
Because it's an async operation. So it takes some time to complete.
looks right to me, yeah
You can also do fun things like storing the Action in a field in the class and invoke it later in another method and so forth
I think it should be:
new A( (c) => { c.GetComponent<SpriteRenderer>().sprite = null; } )
public class A
{
GameObject Asigned;
public A(Action<GameObject> function)
{
function(Asigned);
}
}
Although maybe, you don't need the parenthesis.🤔
assuming "f" = "function", the name of the parameter?
Yeah, that too
Yeah, you can omit the parenthesis if you have exactly one parameter in a lambda expression
I only used lambda with lists
As I mentioned previously all of the stats will be SO themself. Like MovementSpeedStat : BaseStat. Then you just drag them wherever you want. In the effects and in the Stats component.
Actually, Maybe just Stat : ScriptableObject is sufficient. Then it can have string statName field to identify each stat.
Yep
Unless you want some stats to have special functionality.
But I can't think of any examples.
Hmmm...
That should be handled by either effects or your leveling system or something
Yep
isnt that what isDone is supposed to tell me?
In my opinion prefabs would be more messy.
Yeah. But doesn't it tell you after some time?
like having a wait while loop until asyncop.isdone should do exactly that
BUT. Using strings for identifiers doesn't sound right to me, imagine I have hundreds of projectiles and every of these projectile when hitting an object it has to check stats like physical resistance. Finding them with string would be inefficient, right?
They don't need to check strings. They just need to have a reference to the right stat.
my point was exactly that: it feels like resources.unload is not done even if the asyncop it returns triggers "isdone"
You mean, there are still resources loaded?
i mean the resources that are supposed to be unloaded get unloaded N frames after asyncop.isdone
Well, stats can have a set of default stats that it get from StatsDatabase or something. Or all enemies could be variants of a base prefab that already has the base stats set up.
How do you know that?
because the memory profiler tells me that
because the game crashes
because if i wait a second instead than trying to load stuff right after asyncop.isdone then it works
Hmmm... Well yeah. I see what you mean. In this case having a different class for each stat is better, since you can just check the list of Stats with is PhysicalResistance.
but how do you know that asyncop.isdone is true?
maybe it's not true when you try to load?
did you read my code? i have a while loop waiting for that
here
in a coroutine. And I don't remember seeing anything after the loop.
to make it more clear:
- I'm in a IEnumerator coroutine
- I unload my scene "A"
- I create an empty scene so unity has something to hang on
- I call AsyncOperation assetUnload = Resources.UnloadUnusedAssets(); and now i have an AsyncOp i can wait for
- I wait for said AsyncOp to be done in this loop: while (!assetUnload.isDone) yield return null;
- If I load a new scene "B" right now, i have a memory spike as the assets from the old scene are not unloaded yet (even though my while loop had me waiting until asyncop isdone)
share the whole coroutine if you want any kind of advice...🤷♂️
yes, that's where you have while loops yield returning null to wait for stuff
the coroutine really is not the point of my question
But only in the coroutine scope. I've no clue where you try to load the new scene.
i unload right before that while loop and i load right after it
Probably garbage collection hasn't had time to run yet
see https://docs.unity3d.com/ScriptReference/EditorUtility.UnloadUnusedAssetsImmediate.html which specifically waits for GC
thats an editor thing though, cant be used on runtime
what Niktu said. But also share your code. Maybe you're using the coroutine wrong.🤷♂️
sure, but it confirms that UnloadUnusedAssets doesn't wait for GC
that was my guess too, but why return an asyncop if its not reliable?
So why not use separate SO classes for each stat?
again, this is not about how i use the coroutine, i've narrowed my problem down to this
the problem only occurs only if scene A and B are big enough that the memory spike that comes from A not being unloaded when i try to load B is bigger than the memory of the platform i'm building on
if i do this with two empty scenes nothing happens
Better than enums in my opinion. Also, you probably only need to check it in specific places, like Stats.DealDamage or something.
public void DealDamage(int amount, DamageType damageType)
{
foreach(var s in stats)
if(s is DamageResistance dr)
amount = dr.AdjustAmount(amount, damageType);
health -= amount;
}
so yeah, if this is the case, how can i know when dc as freed the memory it's supposed to free, if i cant rely on the UnloadUnusedAssets AsyncOp?
i couldn't find infos about a GC.Collect callback, should I just insert an arbitrary wait of 1s? seems too risky to be the designed usage tbh
I think you can force GC to run in C#? Dunno, never really needed to do anything like that
yeah but the point seems to be that GC is not instant
(apparently Resources.UnloadUnusedAssets(); also includes a a call of GC.Collect)
Sooo... is it actually the way you use your coroutine?😛
The Internet says that GC.Collect is instant (i.e. blocking)
with caveats
what is that supposed to mean?
What I mentioned previously. But I can't say for sure without seeing your code...
so just calling GC.Collect might work
Yep. Sounds like a plan.
As I said, had it in, no difference. turns out the resources.unload calls it anyway,
https://forum.unity.com/threads/resources-unloadunusedassets-vs-gc-collect.358597/
"liortal's guess is correct, Resources.UnloadUnusedAssets is indeed calling GC.Collect inside. So if you already calling Resources.UnloadUnusedAssets, you shouldn't call GC.Collect"
but these could be the thing
GC.WaitForPendingFinalizers();
GC.WaitForFullGCComplete();
though i don't know how advisable is to use those
yeah I don't really know enough to say anything about it
you mentioned a generic misuse of coroutine. i honestly dont understand what among the things i've said could lead you to think i'm using it the wrong way
Just the fact that you don't want to show your code.
As long as we don't see your code, I have the privilege of doubt. 😛
Yeah, that's one way of doing it, although it means that there are some hardcoded stats. Maybe you can have some basic ones like that and additional in a list of additional stats.
AsyncOperation unload = SceneManager.UnloadSceneAsync(CurrentLevel.name, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects); // start unloading scene A
while (!unload.isDone) // wait until scene A is unloaded
yield return null;
AsyncOperation assedUnload = Resources.UnloadUnusedAssets(); // start unloading unused assets (now that scene A is unloaded there's a lot of them)
while (!assedUnload.isDone) // wait until unload has finished
yield return null;
AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(scene, LoadSceneMode.Single); // start loading scene B
sceneLoad.allowSceneActivation = true;
while (!sceneLoad.isDone) // wait until loaded
yield return null;```
if i were to ask questions without knowing what i'm talking about i would write in "beginner-code"
also discord code formatting is really bad
then don't paste directly into discord
I don't know you. I've seen people writing here despite not knowing what they're talking about.🤷♂️
use something like paste.ofcode or hastepaste
Add cs after the backticks.
AsyncOperation unload = SceneManager.UnloadSceneAsync(CurrentLevel.name, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects); // start unloading scene A
while (!unload.isDone) // wait until scene A is unloaded
yield return null;
AsyncOperation assedUnload = Resources.UnloadUnusedAssets(); // start unloading unused assets (now that scene A is unloaded there's a lot of them)
while (!assedUnload.isDone) // wait until unload has finished
yield return null;
AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(scene, LoadSceneMode.Single); // start loading scene B
sceneLoad.allowSceneActivation = true;
while (!sceneLoad.isDone) // wait until loaded
yield return null;```
mmh
not really
i think you need a hashbang or something similar
Well, you can use the base stat references directly where you need them. For example in the damage function. For listed stats, you'll still need to look them up.
like this: ```cs
thats exactly what i did
And the code on the new line
Why?
Scene tmpScene = SceneManager.CreateScene("TmpLoad"); //create temp empty scene cause unity alays need an active scene
AsyncOperation unload = SceneManager.UnloadSceneAsync(CurrentLevel.name, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects); // start unloading scene A
while (!unload.isDone) // wait until scene A is unloaded
yield return null;
AsyncOperation assedUnload = Resources.UnloadUnusedAssets(); // start unloading unused assets (now that scene A is unloaded there's a lot of them)
while (!assedUnload.isDone) // wait until unload has finished
yield return null;
AsyncOperation sceneLoad = SceneManager.LoadSceneAsync(scene, LoadSceneMode.Single); // start loading scene B
sceneLoad.allowSceneActivation = true;
while (!sceneLoad.isDone) // wait until loaded
yield return null;```
its just 3 asyncops, unload A, clean up unused stuff, load B
if A and B are small enough it works, if they are too big it doesnt, cause it seems A doesnt get cleaned up properly
the problem is that load B only happens after "supposedly" the cleanup asyncop is done
Actually yeah, I kinda see the problem. So, whatever you do it's gonna result in a kind of a look up.
which seems not to be the case
so yeah, to get to what was the question all along:
AsyncOperation assetUnload = Resources.UnloadUnusedAssets(); // start unloading unused assets (now that scene A is unloaded there's a lot of them)
while (!assetUnload.isDone) // wait until unload has finished
yield return null;```
how do I get this to ACTUALLY wait until garbage, ALL garbage, has been collected?
Technically it should be collected by the time the asset unload is done. Maybe you have something referenced somewhere that prevents it from being collected..?
And I wouldn't rely too much on the memory profiler, especially in the editor. You can't be sure at what point in the frame it's collecting the data.
i have it connected to the console I'm testing on
but yeah seems like the solution suggested by Nitku could be it
https://forum.unity.com/threads/garbage-collector-does-not-free-memory.1079810/
Well, would be nice to know if that worked.
will have time tomorrow to test
what would be even nicer is for this kind of stuff to be in the documentation 😩
what are you actually trying to do
Judging by the lack of similar issues on Google, I'd guess that it's something specific to your case or platform.
the answer is that Resources.UnloadUnusedAssets is a memory management strategy but a bad one
this appears to be the case
the best approach to manage memory in a video game is to use less of it. is this something you can do?
are you trying to memory manage textures?
there is a checkbox in unity to help you do this
many checkboxes
it's a really, really common problem
the thing is you don't know how your resources are being used. for example, even though an hdri is not visible in a scene, referencing a volume profile that has a deactivated override that references an hdri will still use the hdri, which can easily be gigabytes large
@vivid nimbus have you tried https://docs.unity3d.com/Manual/svt-streaming-virtual-texturing.html
you can't
are you trying to develop for a switch?
if you have a way to measure the process memory usage in game, you can try to detect when that declines
i'm not sure if that's going to be meaningful though
if you're a unity pro subscriber maybe ask in a support ticket
you develop for consoles they'll just tell you
it should be clear though, that you have a halting problem esque situation
how does @vivid nimbus tell the difference between the unity api not working and @vivid nimbus still using assets and thus they are not freed?
Resources.UnloadUnusedAssets() by itself cannot tell you whether your mental model of which assets you're using is wrong
you're probably going to discover you're still referencing something, and that's going to be a very frustrating experience, and that the API has been working all along and we'll never hear from you again
yes I am
besides, I have the feeling the asset usage is fine, it's mainly about when I try to change the reference to a lot of them e.g. by going from a a scene to another that shares very few of the textures and meshes in the first one
that's why i would like to unload everything before attempting to load new stuff
that makes sense, but our game is not using hdr other than for lightmaps, which are scene specific -> are among the things i'm trying to make sure are unloaded before i load new ones
Anyone here any good with Photon?
We ran some tests and it seems like this is whats happening: if you unload a scene and, immediately after, you load a new one unity will have them active at the same time because it seems like always need at least one active scene
yes, a lot of people go into a loading scene on resource contrained devices
you can also build your game like
single scene:
global unified canvas
-> loading screen panel
level prefab 1
then, to transition to a different level, destroy level prefab 1. then instantiate level prefab 2
that's it.
it would have the same exact same end user experience as switching scenes, but the api is cleaner
In a mid-life crisis struggle trying to get a plugin to reference through assembly definition 😢
Apparently the developer told us that the plugin was depreciated and ended product support three years ago. They want to charge us to get their latest plugin... Luckily me, I just so happen to have ILSPY installed 😉
Sure, with the only difference that the unity editor is not made to work with this kind of setup
you can double click on a prefab
it will edit
prefabs are nested
Not to mention if you have lighting data that differs from level to level
behaves better than a scene in almost every way
Plus light maps
yes you will have to use lightsettings
but your goal is to manage memory, so you would have to interact with that anyway
yo, anyone is this official sdl website: https://www.libsdl.org/download-2.0.php ?
Come on, I get where you’re going and yes, it could work better on that side, but it’s like buying a car and drive it backwards cause this way it has a smaller steering radius
All I’m asking is, what is the best way to unload stuff and actually make sure that the memory is free before attempting to load new stuff
this looks pretty promising - https://assetstore.unity.com/packages/tools/utilities/magic-lightmap-switcher-built-in-srp-196489
I’m not asking for a new workflow
for dealing with that problem
Nor for new plugins to add to my project
i'm actually buying it right now 🙂
yeah i hear you 🙂
i want it to work too
it sounds like you should create a loading scene
and switch to it
and unload unused assets inside it
then load the next scene
nbd
i did
That’s exactly what I explained I’m doing
From the beginning
it sounds like you are creating a scene
at runtime
and i'm saying you should just make a scene at build time
called loading
and switch into it
and take care that it doesn't have anything that references the resources you're trying to unload, which can be kind of tricky
since you probably do the whole DontDestroyOnLoad thing
and those objects might have references to things you need to unload
if you already know you just have to wait and then, it does "GC", i think just wait
but like i said, if you look at some outside side effect like memory decreasing, it's not guaranteed to do that
you will need to timeout that measurement
just from looking at your code, the only thing that seems weird to me is the create scene call
so try to not do that, use a build time scene
it might just fix the problem, because the scenes api is horrible
sounds like this guy is pretty frustrated huh
That’s just because unity needs at least one scene to exist so it would keep scene A active until scene B is loaded, unless you go from A to empty scene (the one I create at runtime) and from there to B
Is there any benefit from creating an empty scene at build time, rather than at runtime? The load new level script is literally called every half an hour
Apart the fact that I could recycle the little resources creating an empty scene at runtime requires?
it's just my gut feeling that, since i have been using unity for many years and never interacted with CreateScene at runtime, it is probably a crusty part of the API
and may behave in surprising ways
the only other dubious thing is using a coroutine to do this
but i really doubt that's going to be a problem
The memory used is literally the same, we’ve been running tests for some days already
it's not about the memory usage
it's that, just because, unity might unload assets correctly when you switch between build time scenes, and not when switching runtime created scenes
like i don't want to use the word bug, there's definitely a bug (you expect the memory to be released, and it's not)
And as I said, the code already works if I put in an arbitrary time wait after unloading A, before I load B
you could try it?
or file a bug and wait 9 months
for unity QA to get back to you and ask you to see if it repros on the latest unity
i'm telling you the only two possible things wrong with your code
i don't mean wrong*
i mean two opportunities for a workaround
one is try a build time loading scene, and another wil lbe to not use a coroutine
because coroutines running on objects that cross scene loading boundaries (i.e. dontdestroyonload)
sounds very finnicky
I will when I’m back at work tomorrow, but my question was “is GC.Collect immediate, cause it doesn’t seem it is”
How are you supposed to go from one scene to the other then
Without destroying and reloading everything
dontdestroyonload is fine
i'm just saying that a coroutine running on an object with dontdestroyonload, that is itself doing scene changes, i don't know, i can see that being buggy
but that would be the last thing i try testing
if i were you
GC.Collect isn't immediate, it never was
it's just a copy of Java's gc behavior exactly, which is a request, not an order
Cool, that was the only answer I needed
i think you're going to find the thing
it's probably going to be a coroutine from the previous scene
and that's why it's time related
Except for, question 2: is there a callback or a way to know when go has collected and memory is free for real
there's some object that is sticking around, with all its references
something with an animation expressed in a coroutine*
pretty common unity gotcha
so technically it's still being referenced
it's already giving the right answer
i don't know what to tell you, the likely outcome is that the bug is that you're referencing something "still"
and it's just going to be surprising what it is
and the fact that it appears to go away "a short while later" is a red herring
it sounds like a coroutine-expressed animation that's still running
and instead of like, stubbornly asking the same questions over and over again which you know the answers for, let's just brainstorm what you might be referencing
The loading scene is the only coroutine in the game afaik, unless there’s some in the only external bit of code we use for aUi
you might have invoked something that is a coroutine on a dontdestroyonload object
yeah
it might be like DOTween or whatever
i know iTween has this bug
i don't know about dotween, i stopped using itween years ago
but yeah, maybe that's not it
another thing is a scene wide thing, i know you don't use hdris
We had that in from more than 6 months now tho, so I guess that would have surfaced before if it was so game breaking
but it may be something lightmaps related
yeah
it's really tricky
you can test your code switching between scenes that don't have any code
How could it? I mean light maps are scene-specifi
like are just static unity scenes
i don't know, i'm just spitballing
all this stuff is glitchy 😦
let me know tomorrow when you try some stuff
you'll figure it out
I really wish I didn’t have to 😩
2d bool array is size 3000 by 3000
v2int2 is same thing as vector2
with this size I can check positions -1500 -1500 to 1500 1500
(positions are int and can be true or false, tilemap sort of)
doing this 45000 times causes lag, how improve?
- do it less often, or with smaller queries, or over multiple frames
- do it in parallel
- find a more efficient way to do whatever you're doing
- do it in parallel
wdym?
The job system is something you could look into that allows this.
job system?
Are you a parrot? You haven't even searched for any of the key terms
This is #archived-code-advanced . A certain level of competence is expected if you're going to ask questions here.
if it's not required to do it all at once possibly consider chunking
Can you pass a GameObject that's present in the scene into the variable slot of a Component in a prefab?
I want to put one of my UI elements into a Scriptable Object so that I can change it's Sprite
nope you're gonna have to assign it in a script
but that's easy with GameObject.Find
and similar funtions
Yeah, that's what i've been using so far. Was wondering if there was a better way, but good to know that there isn't :c
nah sorry idk if there is
Usually you should have whatever instances it call an initialise function with the parameters it needs to configure those missing instances
What i've done is a Scriptable called HUD Elements and it just assigns all the needed UI elements to their necessary variables in the Awake function
Can learn a lot lurking here
Why?
Do I need to create two different scriptable objects if, for example, I want two players to have the same ability?
Multiplayer
yes
You can reference the same SO for both players
yeah
no need to use two
I mean you could do like this if this is what you mean
MonoBehaviour>Health(SO)>Ammo(SO)>PlayerController
Like this would reference from those scripts
i think
I'd only call the Initialise from the player if they're the local player though, right?
What networking solution not that it matters?
Mirror
I'm just wondering if, for example, if two people in a MOBA are playing as "Speedster"
Yeah i assume that is how it works i think they have a HasAuthority thing or somin
Are you trying to check whether they are local based on their names is that how mirror works?
i have a Handler variable in my scriptable objects in order to tell who is using the ability but
Thinking back... that's probably a bad idea; and parsing in the gameobject that calls it would be better
Bro scriptable objects are just data containers
Think of it as if you’re playing dungeons and dragons
I need my scriptable objects to have functions in them; so a little more than data containers in a sense but
I get what you're saying
you have your character and its stats and abilities
But you are the player instance
And you manipulate those stats
yeah; I just need to parse the player in on function calls
You use abilities
No
Rethink that
SOs are not intended to manipulate gameobjects
Sure you can do that with bunch of callbacks etc but it’s usually wrong approach
It's literally what it says on Unity's official website regarding using SOs to create a MOBA
It's hard, I've done it, and it works, but it's hard.
Yeah i’ve done it too
In this recorded live training session from August 2016, we create a flexible player ability system which includes player abilities with cool downs, similar to those seen in MOBA or MMO games. The approach uses scriptable objects and is designed to allow game designers to create multiple variations of an ability and swap between them easily.
To get callbacks on dialogue options
Interesting. I kinda like that
the thing that's throwing me
is where the tutorial has a variable called rcShoot
and sets it to the Triggerable Component of the object that parsed in
like; would that not just set rcShoot to the same Triggerable on all clients...?
Nope, each SO is its own instance
You can multiply them at runtime
Same idea as having multiple Monos, setting a field on one doesn't affect others
I have Gun (ScriptableObject),
and I have GunAssaultRifle (Gun)
GunSubMachineGun (Gun)
so if I create an SO from GunAR and call it M556
then put M556 in the PlayerGun script's Gun firearm field
each GameObject would have an independent M556?
You mean just dragging the SO to multiple Monos? No, they'd all reference the sameSO
You can get around this with ScriptableObject.CreateInstance I think
Hey, before you leave
That comes with its own issues, sometimes the Data and references don't get copied properly, if I remember correctly
So you might want some sort of Init method
You're just creating an instance of the SO in that case, IIRC, so its fields, etc aren't copied over like you may think it is. (I think, just keep an eye out for it)
Hmmm, wouldn't Object.Instantiate not be a better option in that sense?
Store my M556 SO in a dictionary (I made a custom dictionary serializer for Unity's Editor) and then use Object.Instantiate?
I vaguely recall being told to use CreateInstance instead
Hmmm, I see
Instantiate clones the original object, and returns a clone;
Whereas CreateInstance creates an instance of a ScriptableObject
so I think in this case; Instantiate would Clone M556, whereas CreateInstance would just create another GunAssaultRifle, and not an M556
which is why you're encountering issues where data doesn't transfer over
Very well could be. I haven't tried to use it in a while, memory is foggy on it now
Just giving you a heads up
But thanks for the clarification, makes sense now
Appreciate it 😄 I'll have a little fiddle around with the different options and see which one works best. Thanks for your help, enjoy the rest of your evening/morning depending on time zone
GL HF
Trying to run https://github.com/keijiro/Rcam2 on 2020.3.19f1
Getting this error: Library/PackageCache/com.unity.render-pipelines.high-definition@10.6.0/Runtime/Compositor/CompositionLayer.cs(60,26): error CS1069: The type name 'VideoPlayer' could not be found in the namespace 'UnityEngine.Video'. This type has been forwarded to assembly 'UnityEngine.VideoModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' Enable the built in package 'Video' in the Package Manager window to fix this error.
However the the built in package 'Video' in the Package Manager is non-existant.
Every time I get an error like that, I just reset packages to defaults and they go away
are there any code implementation for tiling hemisphere partition into equal cells, like in this research paper:
https://www.sciencedirect.com/science/article/pii/S0925772112000296#se0010
That is so damn specific
I saw a similar tiling system in the game Dyson Sphere program, so as I searched I came accross this article but I couldn't find any implementation, I guess I should roll my own
I was thinking it looked just like DSP when I saw it heh
Sebastian Lague made a video on sphere generation with equally spaced points, I think? Not sure if that'd help you out with a grid though
thanks, I will look into that
The fact that you have this paper is already amazing.
Guys, I don't get meta files.
I'm doing this internship for a small studio, and they told me to stop committing the meta files that unity automatically adjusts when I for example, open up a scene.
They work on Mac, I work on PC, so a bunch of my meta files get adjusted when I open up the project. Even things that have nothing to do with what I was working on.
I always learned that it doesn't really matter if you commit these. Now I'm being told to stop and stay picky about them. I think that's just going to give me a ton of headache by having to resolve merge conflicts and picking out the right meta files for each commit.
What should I do here? What is the way to go? Are they right in saying that simply opening a project has messed up some of their references in a different scene? Because I hard-doubt that tbh.
can't find anything in the docs that says you'd have to do that either.
The meta file is how Unity tracks objects. If you create a new asset, but don't commit it's meta file any references to it will break, as Unity will see it as a new asset the next time it is imported. So yes, it is important to commit them.
Resetting packages lost all the kejiro packages. I guess I would have to resetting and then re-add them manually?
right I understand that, but simply opening the project on my PC changes a bunch of meta files. That shouldn't break the references though right?
Sometimes Unity will just touch up meta files that are not to do with changes you have made. If you're committing meta files related to changes that you have not made, just discard them. If they keep coming back then it's only sensible to commit them.
Probably, not sure. I've never had issues after the reset myself
my point being that if I have to manually select my meta files, I'm probably more likely to not commit one I actually need, thus breaking references in the process.
While I cannot see how simply opening the project would break any references on my end.
What are the actual differences in the meta files
No, they are stable across platforms. Something to keep in mind is that Git (I assume you use git because you said commit) doesn't track folders. That means any folder you create locally will constantly be reimported by Unity creating new meta files because it doesn't exist in version control.
Also, you should really know what files you have changed and only submit those
You really should just be careful about what you are committing. Don't be carefree about discarding things, but it should be obvious enough what you haven't touched
Opening a Scene shouldn't change meta files unless you use a plugin/package that does so. However opening a scene might cause asset changes
Oh yeah actually, it's possible that since you are opening it on Windows you are causing the asset in question to apply some platform specific settings. This can cause a change in meta files, notably importers.
Minor version differences can touch up meta files. Selecting assets even when not working on them can do it. When working in a team with version control it's courtesy to not dirty things unnecessarily. Sometimes Unity can fuck up and break things, so looking at changes you've made before you commit them is also a good thing to do.
weird
Using an ableist slur is not the same as swearing. If you're not here to talk about code, don't talk.
!mute 181873334818963457 My perception of the rules: come back tomorrow when you have a code question.
#3520 was muted
If there were children here i assume theyd be banned since thats against Discord TOS but go off ig
Hi, I am trying to deserialize this with JsonUtility and now trying with Newtonsoft, but not getting a lot of success.
public class TokelToken
{
public string tokenid;
public string owner;
public string name;
public int supply;
public string description;
public string[] data;
public int version;
public bool IsMixed;
public int height;
public string ownerAddress;
public int blocktime;
public string blockheight;
public int syncedHeight;
}
TokelToken tt = JsonConvert.DeserializeObject<TokelToken>(mytokens.downloadHandler.text);
Your root is not your object directly, but rather an object that contains a list of what you want
I think I am doing something entirely wrong because my class covers one item
@fresh salmon can you help me to get into the right direction, never used lists or json before in unity :S
So
public class Whatever {
public List<TokelToken> tokens; // { "tokens": [ your items here... ] }
}
Whatever root = JsonSerializer.Deserialize<Whatever>(json_text_here) would do the trick
Because you don't have a single token, but a collection of them, and they all are under a key named tokens at the root of the JSON
so i need another class to wrap them into?
ok, understood
how do I deal then with data?
its like a nested thing inside token
"data":{
"raw":"f70101fe65530600021068747470733a2f2f736974652e6f7267030104050202abcdef",
"decoded":{
"id":414565,
"url":"https://site.org",
"royalty":1,
"arbitrary":"\u0002\u0002���"
}
},
does that also needs its own class?
Yup
or is string[] good enough
If you don't need it though, no need to create a specific field in your class, the serializer will ignore it
hi, how can sop modifying collections while iterating over it in this script? ``` public void Update()
{
t += Time.deltaTime;
if (t > 0.1 && l1.Count >= 1)
{
t = 0;
foreach(helper h in l1)
{
helper2 = h;
helper2.activate = false;
helper2.highlight = false;
l1.Remove(helper2);
}
}
}
private void OnTriggerEnter(Collider col)
{
if (col.gameObject.GetComponent<helper>() != null)
{
helper = col.attachedRigidbody.gameObject.GetComponent<helper>();
helper.activate = true;
helper.highlight = true;
if(l1.Contains(helper)==false)
l1.Add(helper);
}
}
private void OnTriggerExit(Collider col)
{
if (col.gameObject.GetComponent<helper>() != null)
{
helper3 = col.attachedRigidbody.gameObject.GetComponent<helper>();
helper3.activate = false;
helper3.highlight=false;
1.Remove(helper3);
}
}
}```
Don't use Remove in a foreach loop
but its possible if you remove the null elements somehow i guess
like in this example https://stackoverflow.com/questions/46247501/collection-was-modified-enumeration-operation-may-not-execute-unity
You can do this:
for (var i = list.Count - 1; i >= 0; i--) {
if (condition) {
list.RemoveAt(i);
}
}
You need to move backwards through the list or else you'll skip elements
Wait... why is this question in #archived-code-advanced?
This really isn't #archived-code-advanced though
because nobody would give answer there
where please post in the correct channel next time
Typing "forr" and hitting tab will autocomplete a backward for loop in most IDE btw
ok thank you guys, i guess i just dont use foreach with lists
even if it is possible somehow
but i guess this is not for advanced code
No, you just don't modify collections while using a foreach
@fresh salmon I get
Argument 1: cannot convert from 'string' to 'Newtonsoft.Json.JsonReader'
when using
Tokels tokeltokens = JsonSerializer.Deserialize<Tokels>(mytokens.downloadHandler.text);```
Just dont modify the list like add/remove in the foreach loop and youre good
ok thanks
Oh sorry, the method is DeserializeObject<Tokels>. I'm too used to another serializer.
Good afternoon community.
Question regarding GetField() and there around.
Concider the following elements:
public class Player
{
public int itemA;
public int itemB;
}
public class PlayerCharacter : Monobehaviour
{
public Player player;
}
I understand I can use GetField to get the hold of itemBs value, but how do I write it?
i understand now: the fix is to clone the collection with toList/toArray. so as i said there is a fix
but thanks
GetField as in the one in System.Reflection?
aye
That's an awful fix. Just remove it with a reverse for loop like Rhys provided
It has set value and get value functions. Though why you'd need reflection is beyond me
I have a set of conditions for skills/abilites I need to compare them with, and they vary on each skill. So I need to retrieve a value in a class based on what condition are set up. Conditions are set up using enums
i did that before and its not working for that case
Still doesn't require reflection as far as I can see
due to the physics and framebased timings
That has absolutely nothing to do with anything we're talking about
NREs are not advanced. Ask in #💻┃code-beginner or #archived-code-general
srry
right.. so how would you do it then? use for loop to compare strings?
I have no idea as to the specifics of what you're doing. Why would you need to do string comparison? Enums are just fancy integers. If you use them to index multiple things with dictionaries or lists then you can link them together easily
@fresh salmon I got the right method now, but as I thought the data object gives me horror:
ArgumentException: Could not cast or convert from System.String to TokelDataDecoded.
if a skill has set a requirement of strength 5. I want my function to check the value of player.strength, but player.strength is not a string.. so how do I search and retrieve it?
and bear in mind another condition may want to search for Hitpoints, intelligence .. or even bools.
Why do you need to "search" for anything? Interfaces, composition, etc. Why reflection?
@fresh salmon I made Tokels, TokelToken, TokenData and TokenDataDecoded
public class TokelData
{
public string raw;
public TokelDataDecoded decoded;
}
and
public class TokelDataDecoded
{
public int id;
public string url;
public int royalty;
public string arbitrary;
}
Then you have a field or property that is of type TokelDataDecoded, but it expected a string.
Hm if I remember right that structure is correct
I want to get the field of a class to check its value, and it needs to get that no matter what field I am trying to compare with the conditions..
"data":{
"raw":"f70101fe65530600021068747470733a2f2f736974652e6f7267030104050202abcdef",
"decoded":{
"id":414565,
"url":"https://site.org",
"royalty":1,
"arbitrary":"\u0002\u0002���"
}
},
System.IO.File.WriteAllText(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + "\\New Folder\\test.txt", "Test"));```
I probably can't use these File Directory stuff in a WebGL build, correct?
Yeah that looks good to me, try commenting the public TokelDataDecoded decoded line, and see if the error is still there.
You should probably post some code, or more fully describe your setup so someone can help you organise the architecture better. I'm just on my phone rn. There's little to no reason to use reflection for gameplay code though
@fresh salmon nope, then no error
Then look at the JSON, there might be a token which data.decoded value is a string, and not an object?
Maybe do something inside the class and deserialize the string into the TokelDataDecoded?
they are NFT, so they should be all object :S
If you don't find any, then inspect the exception, especially the stack trace and the inner exceptions if there are any.
You'll need to set up a try-catch block, and debug using VS (breakpoints, step-through code) to inspect the exception.
I have to go, if you have more questions post them here, someone will take the lead
Got a question about serialization and reflection
- I have a
ScriptableObjectcalledUpgradeSettingswith a serializedListof instances of a plain C# class calledUpgrade - The
Upgradeclass isSerializableand contains anotherListof instances of C# classPowerUp - The
PowerUpclass is alsoSerializableand has yet anotherListof instances of C# classPowerUpEffect PowerUpEffecthas a variety of derived classes, likeHomingBullets,ExplodingBulletsand so on- I use reflection to create instances of the various derived classes and put them in the
ListofPowerUpEffectinstances in thePowerUpclass - I then use reflection to get all the values from the instances and display fields for editing them.
So far, so good.
Problem is that once the asset database refreshes, the serializer seems to turn all of the instances of the derived classes into instances of the base class! Is there any way to work around this?
That will happen if the types are not UnityEngine.Object types. You can use the SerializeReference attribute to serialise polymorphic data otherwise @distant gyro
Ahh.
Let's see if that does the trick ...
@austere jewel SUCCESS!
Thank you! I now also have a really weird feeling of deja vu like I've been here before asking a similar question and gotten the same answer from, uh, you.
send it and people will see if they can help
if anyone can help pls dm me (neural networks)
This isn't how this discord works. You're free to ask your questions in one of the channels. If anyone can help, they will.
why is only one of x of my game objects affected by neural feed?
sure
here you go
Is there a way to change the way the renderer sees objects from Normal to Wireframe without having to swap out materials or create a custom shader? I am using URP 7.7 and Unity 2019.4 LTS
what do you mean? runtime? editor? in scene view you can change from shaded to wireframe, if that is what you want....
Hi, I tried to understand how to do some exercise in the second script " handle when color is selected"
https://paste.myst.rs/xf5pai2g >> ColorPickerScript
https://paste.myst.rs/v6ologfz >> MenuUIHandlerScript
a powerful website for storing and sharing text and code snippets. completely free and open source.
a powerful website for storing and sharing text and code snippets. completely free and open source.
are you getting an error? if so, tell us where or we can't help you as easily
i see many potential issues so specify the line that has an error on it
for example, you named a variable the same as a type in MenuUIHandlerScript
Okay, I tried to do something in the second script I need to add some code
you also never use your iterator variable in NewColorSelected and you assign to its parameter
many many issues so we'll go one step at a time
run it and send the first error
{
// add code here to handle when a color is selected
ColorPicker.ColorButtonPrefab.onClick.AddListener(() =>
{
color = ColorPicker.SelectedColor;
});
}```
that's not an error
you already sent that code and it has lots of problems which i mentioned earlier
When I start the game I can select one of the colors. I can press start(to move to another scene) and exit
ok but what's the error
there are lots of mistakes in your code, i need to know where to start
I don't have any errors.
My point is I should handle the color which I selected but I didn't do it correctly
if you don't have any errors you're running it very wrong lmao
there are lots of mistakes in your code that should be causing errors
wtf
are you sure those scripts are running? bc maybe they're just never running
which might be why they aren't causing any errors
It's my exercise from the course I got to this game with scripts to add some things and optimize the code. Everything works but I don't understand how to do it I checked every forum and yt but I don't know who to handle the color
so you didn't write these scripts? they are someone else's?
no, they're not unity's
there's no way unity would distribute code with mistakes like that
"project brief"
idk man i don't see anything there about switching colors
how did you download those files?
point 5 there is a link
yeah i see that but it doesn't link to the actual cs files
where are those am i stupid 😂
is it possible for the main thread to execute a method the second time simultaneously?
no, you would have to run it on a new thread
that's kind of the point of threads, they allow you to do more than one thing simultaneously
i have a situation where a global list is being modified while running the same method multiple times
ah no, i don't want it to be done simultaneously
you said that
@elfin tundra I'm sorry there is instruction 😅
no, i asked if it's possible for the main thread to access it simultaneously
cause i'm only using the main thread
you said execute but anyway wdym access?
In this tutorial, you’ll learn about the basics of Version Control, and the reasons to implement it in your own projects, even if you’re developing applications by yourself. You’ll also learn about the different Version Control options available to use with Unity, and put your new skills into practice by downloading the project that you’ll use t...
as in modify the list
i have a method that modifies a global list
@elfin tundra In materials.
Provide said errors
wtf lmao why did they provide that code
not sure how helpful this is though since a lot of stuff is going on
basically the order is this
enter method, modify public list, copy public list to internal list, do stuff with internal list, done
Do what stuff?
@elfin tundra I really don't know but it's hard to understand 😳
Stuff isn't helpful
Especially when your internal list, might just be references to things in the public list
well it's using that list to generate the collision boxes
can't show the entire code lol, its like 2000 lines, but maybe i'm copying in the internal list wrong? 🤔
i'll try posting some stuff
@elfin tundra What do you think about it?
The most important part is likely the method where this error occurs
That shouldn't be 2k lines
i think they provided bad code and you should write it yourself from scratch so it’s right and so that you learn what everything means
This all seems like #💻┃code-beginner material
yeah
If you don't know how to code you're in the wrong room
def go there now
Okay
i think maybe ask in #💻┃code-beginner
They just did...
Thanks, I did it 😉
there are a few things going on that are hard to understand at first
// global list
private Dictionary<string, Dictionary<string, List<byte>>> blocksWithAllPaths = new Dictionary<string, Dictionary<string, List<byte>>>();
// enter of method
// global list is being modified
var blocksWithPaths = new Dictionary<string, List<byte>>();
// assign values from global list to internal list
List<byte> bytes = null;
foreach (KeyValuePair<string, List<byte>> each in blocksWithAllPaths[chunkKey]) {
bytes = new List<byte>();
foreach (var each2 in each.Value) {
bytes.Add(each2);
}
blocksWithPaths.Add(each.Key, bytes);
}
// start of a bunch of while loops scanning around blocks and building the paths
var blockToBeModified = blocksWithPaths[key]; // block to be modified with key being the current block being worked on, this is where error occurs
// end of while loops
best i can do
what is your goal here?
Christ, I'm gonna need a minute
it's a method that generates collisions around 2d blocks
are you trying to find a path between two blocks in a 2d or 3d space?
what does that mean, generate collisions?
anyway, you are adding to a dictionary while enumerating through it
you can't do that
lemme help you see what's really going on
He isn't doing that
i'm not adding while enumerating
blocksWithPaths is being enumerated, and within the enumeration, there's an .Add
He enumerates through blocksWithAllPaths and modifies blocksWithPaths
it looks like it's not being enumerated
It's a key not being present in the dictionary
oh
key exception
yeah
i don't know this is a mess
what are you trying to do? @frail dock express in words
don't send a video
you don't know the half of it, 😄
well, it was working fine, the whole point of the global list was to update only the blocks around the one being modified to increase performance
ergo the global list
as i said, it's not, the everything is spread, you can't possibly understand any of it unless i post the whole thing
Paste sites exist you know
ahh, i'm a bit worried of code snatchers tbh
There must be an easier way than a Dict of string, Dict of string, List bytes
Nobody will steal this code...
just express in words what the goal is
oh i've seen part of your video before
you're trying to generate a collider for a tile map that gets modified?
yup
well it's not tile map, it's a mesh
it goes modify block list, modify mesh, generate colliders
usually if you try to use the fewest colliders or whatever, it performs worst in the most common case
but the colliders part took a shitload of time to optimize for performance
yeah
i got it down to 10ms
but this last part would get it down to 6
i just don't get how the list is being modified simultaneously
it looks like you probably just accidentally deleted the key before you use it again
unless i'm missing something
well, what's I think happening is the internal list is being modified with outdated information
hmm, well it's a bit hard to explain, the part i'm optimizing builds a mini map around each block so i can identify exposed sides and cover them with collision points
that's what that list of bytes is
so if any empty sides are detected the while loops keeps going until all sides are covered
In runtime like a wireframe effect on all materials
i'm guessing if it's going too fast one of the maps is wrong and ergo the key error
but how can the list be modified twice if it's only on the main thread 🤔
it would just be a bug
it wouldn't be going too fast or anything like that