for (int i = 0; i < triangulation.indices.Length; i += 3)
{
nodesCount++;
Debug.Log(triangulation.vertices[triangulation.indices[i]] + " " + triangulation.vertices[triangulation.indices[i+1]] + " " + triangulation.vertices[triangulation.indices[i+2]]);
// Add each edge of this triangle
if (edges.Add(new double[] {
triangulation.vertices[triangulation.indices[i]].x,
triangulation.vertices[triangulation.indices[i]].y,
triangulation.vertices[triangulation.indices[i]].z,
triangulation.vertices[triangulation.indices[i+1]].x,
triangulation.vertices[triangulation.indices[i+1]].y,
triangulation.vertices[triangulation.indices[i+1]].z
})) edgesCount++;
if (edges.Add(new double[] {
triangulation.vertices[triangulation.indices[i]].x,
triangulation.vertices[triangulation.indices[i]].y,
triangulation.vertices[triangulation.indices[i]].z,
triangulation.vertices[triangulation.indices[i+2]].x,
triangulation.vertices[triangulation.indices[i+2]].y,
triangulation.vertices[triangulation.indices[i+2]].z
})) edgesCount++;
if (edges.Add(new double[] {
triangulation.vertices[triangulation.indices[i+1]].x,
triangulation.vertices[triangulation.indices[i+1]].y,
triangulation.vertices[triangulation.indices[i+1]].z,
triangulation.vertices[triangulation.indices[i+2]].x,
triangulation.vertices[triangulation.indices[i+2]].y,
triangulation.vertices[triangulation.indices[i+2]].z
})) edgesCount++;
}
Debug.Log("NODES " + nodesCount);
Debug.Log("EDGES " + edgesCount);```
#HashSet question
1 messages · Page 1 of 1 (latest)
I have this code that attempts to get a hash set of every "edge" in all the triangles without any duplicates
however, the amount of edges is returning exactly 3x the amount of nodes, which imlplies to me that the hash set is not considering any of these sets of 6 numbers (2 coordinates) to be duplicates
I'm thinking it maybe the orders are different and that's why they are considered different. but how exactly does the hash map determine if an object is already in the map or not?
also, is there a data structure that would include say 6 numbers without ordering them and be considered identical to another set of those same 6 numbers?
like the hash map isn't comparing the data address of these objects right? it IS comparing the contents itself I hope?
It's comparing the refetences(you can say addresses) of the arrays that you create each time. Even if 2 arrays contain the same data, they're 2 distinct objects that would have different hashes.
hm ok. is there a data structure that works like this? I don't want to compare every edge (as in one of three edges of a triangle) to every other edge in the entire "navmesh" because it feels like there should be a better solution
basically I am trying to recreate a graph from the triangulation of the navmesh (since it bakes it for me) and a triangle would be connected to another triangle if it shares an identical edge
I COULD theoretically put them all in a giant list and compare each one to each remaining one but I don't want to do that if someone knows a more efficient way
especially since in theory looking up if an entry already exists in a hash is way faster, right?
Like is it even possible to have a solution faster than comparing every edge to every edge or should I not waste my time trying to find one
You can create your own class/struct with 6 values and provide your own hash calculation from the values. The hash map would then only compare hashes.
Object equality and hashes is a pretty deep topic, but basically you need this:
Override Object.GetHashCode so that two objects that have value equality produce the same hash code. This is required for correct behavior in hash-based collections like Dictionary<TKey,TValue> and HashSet<T>. Objects that are equal must have equal hash codes, or these collections won't work correctly.
That being said, I feel like you're getting into a rabbit hole that's not gonna provide the results you expect. As I said earlier, it might be better to just consider other non navmesh solutions.
I thought this WAS the non navmesh solution
it does seem like a very odd thing to need, but also you might run into issues when creating a hashcode from 6 values. if this is for some editor only functionality so you can build your own graph, then just compare every value yourself
the only way the navmesh comes in is providing the base verticies
Not at all.
I was implying looking at various third party A* solutions/plug-ins.
I agree that it's kind of a rabbit hole, which is why I was surprised unity doesn't let you do this by default. I'm not sure you could really build any kind of advanced pathfinding without being able to weight the graph in realtime
navmesh is very much a "take it or leave it" solution
unity could make things more customizable to an extent, but there will always be someone wondering why they cant do XYZ
sure I just think weighting certain areas without having to rebake the mesh is a pretty essential feature imo, but oh well I cant do anything about it
i didnt see the context in how you're trying to use it also, but navmesh areas can have weights applied to them
You should be prepared for something like this if you're using a close sourced engine. They can't expose their whole implementation and can't cater for every used needs.
You can update the mesh at runtime though.
well I don't really know of any 3D engines besides this, Unreal, and Godot. making 3D rendering code is definitely out of my skill level
you can like cut it or whatever, but I want to weight certain areas not just remove them
only with static areas though
what im trying to do is weight nodes that an agent is currently using to encourage enemies to take different paths
Yeah, honestly, area costs are probably a very niche thing for them. I've never had the chance to use them.
This is pretty much getting into the innards of the implementation. And they decided not to expose it to users.
which is why I need to make my own navmesh and run my own algorithm on it
are you saying that the hashmap DOES use the faster lookup IF the generic is of a type that has a hash generation method, but just uses the address if it doesn't?
I'd just recommend using an existing solution. Like A*.
It uses the address for reference types by default. That's pretty much it.
but then there's the problem of translating the path on the graph to the actual geometry of the polygons but thats further along
You can generate a graph easier. Just check collisions at regular intervals. No one said you need to iterate every mesh vertex.
idk what this means
Well, you can have a 3d/2d grid. That's your graph basically.
You can add walkable and non walkable areas by checking if a point is inside geometry/collider or not.
And the A* package already handles that for you AFAIK.
A* is an algorithm, idk what you mean by A* package
There is a very popular third party plugin/asset called A* after the algorithm
ah
If you googled "a* unity" it would probably be one of the first results.
I think I saw that but you need to pay for it to generate a navmesh. I want a navmesh because it's more precise (its for a 3D fps) and it's also a lot less points in memory
and I think I'm almost there
at least for MAKING the graph
the main issue is if making it will be efficient, since I think I have to compare each line to each line
maybe I could bake it, but im not sure how that works in Unity. probably it puts it in a file somehow?
well I would cache it either way, but I mean in a serialized form vs when you load the level
I COULD maybe just pay for it, but I feel like this gives more control and hopefully will help me learn something.
hm it is expensive though
I still have the question, if I override this method will that mean that using a hash set will become faster than putting each "line" in a list and comparing them one by one?
I suppose it doesn't matter a TON if I'm baking this anyways. like 2000 triangles PROBABLY wont take more than a few minutes to bake...
i doubt it'd even take minutes. my main concern would be how you plan to pack 6 floats in an int with minimal collisions. You might not know if your algorithm fails due to 2 random objects generating the same hash code
hm ok, I don't actually know a lot about how hash data structures work. someone told me I should try to use them for an algorithm that compares a lot of things looking for duplicates, since they have fast lookup or something. but you are suggesting not everything fits well into a hash?
do you think it would be slow to compare all of them more directly
something like
take each triangle, and then for each line of the triangle, compare to every other line in the set and if a duplicate line is found, remove both lines from the list and connect those two nodes in the graph
Of course yes it'd be slower to compare all 6 points in your object to another 6 points, relative to comparing the hash code which is just an int. Youre running more logic
but would it not compute that anyways during the hash calculation?
either way, would it be so much slower that it causes issues do you think?
computers are usually faster than I expect tbh
You would need to try it and see, I cant tell you if it'd cause issues. Anyways you would be saving this data anyways so its not at runtime
true, I have to find out how to serialize data I suppose. there's probably some "proper" way to do it with unity, rather than making a text file lol
And yea I guess the hashcode would be computed everytime unless you cache it
but thats a different question at that point
To be fair, the entirety of what youre doing is not the proper way already
I don't really know of another way that doesnt cost a lot of money
You have many options, json, csv, binary.
Unity serialization in scriptable objects
For the saving part*
I thought you were referring to the whole making a graph thing.
is that what it's referred to, just serialization in the unity context? if I wanted to look it up in the documentation etc.
but yeah I think I will just manually compare all the lines
it cant take longer than baking a lightmap
I was referring to the whole thing when saying its already not the proper way. My suggestions above were just other ways to save the data
yeah, and I was saying I dont know of another way to do what I want to do lol. plus it feels like I COULD do it. it doesnt seem completely out of my grasp like 3D rendering would be
For your actual graph, its hard to suggest much because a lot of it depends on game design. You could get pretty far with just a grid represented in a 2d array (or flattened to be a 1d array)
well, it is a 3D FPS so it has to at least be 3D. and I think a navmesh would be better because of the scale and precsision. its something similar to Quake.
I think I will just go with the algorithm I came up with, and just deal with however long it takes. then I have to implement A* on it which shouldnt be too bad. and then like "optimize" that path so it fits the actual geometry instead of the underlying nodes.
avoiding the other enemies might be difficult but maybe I can just use the physics engine and not move them into a place where an enemy already is
I mean, if you're dead set on implementing it yourself, you're free to do whatever.
It's just that navigation is a pretty advanced topic, and it's gonna be very difficult to implement something decent(competing with existing solutions) without deep C#(and programming in general) understanding.
Also, I'm pretty sure the A* project has a free version. You could take it as a base and extend on it, instead of reinventing the wheel.