#archived-code-advanced
1 messages Β· Page 30 of 1
I appreciate this. It makes a lot of sense, however still, I want to implement diffie hellman as my security layer, because it is the one I most understand. So if I cannot use system.cryptography, I will write my own implementation that is safe for unity. I despise certificates with passion.
Diffie Hellman is incredibly simple.
π«‘
@undone coral I really appreciate your advise though. And I am grateful for your help on this. I know at least that I need to find another approach.
if i were you, i would write the master server as a bog standard http server
truly what the world needs is an openapi generator for unitywebrequest
because that's really how people author this stuff, they use an IDL
it's up to you if you want to use grpc or openapi as an IDL
everyone winds up doing this
so if i knew someone who was skilled at programming and capable of concentrating (you)
and it was like "make your own diffie hellman" or "make an openapi generator for unitywebrequest"
hmm. i would choose #2 please
that will be very impactful for networking innovation in unity π
There is no escaping the use of TCP for my master server. If I implement an API, it is just a second project to add to my overhead. The master server must communicate with a spawner server, and with a game server. I don't see how an API can communicate back to a client.
with respect to getting fishnet to work... hopefully you are making a steam game, so you can use Steam Net
everyone who does UDP eventually either reimplements a half thought out crappy version of STUN/TURN/ICE or uses STUN/TURN/ICE (i.e. webrtc)
if you look carefully at what steam provides it will be very informative as to how these games really work
steam provides TURN servers
as their implementation of networking
this is coming from someone who has operated multiplayer realtime games at scale
again i'm only talkinga bout this since you seem to be focused on education
partly*
do you have any screenshots of your game by chance?
I do.
The master server must communicate with a spawner server,
this is reimplementing a half thought out crappy version of kubernetes, or at least hashicorp nomad counsel and terraform, and keda π
i'm kidding but seriously there's a ton of stuff that already exists that smacks you with where the journey leads
that looks nice
Thank you. I've been developing this game for the last 5 years.
including learning from 0?
Yes, I started this project with no game development knowledge.
sick
it's essentially a bullet hell/boss battle type game, with pvp in the mix.
there's a lot of potential for MMO Star Control II
emphasis on 2D, so that everything eventually gets shipped lol
counting in years is really misleading π someone with 0 prior knowledge and not working on it fulltime will still be compared to those that did
it looks great
don't tempt the poor guy with MMO ambitions
This is an MMO, hence the master server.
oh boy, have fun with hackers and bots and lack of playerbase then
no need
The server is fully authoritative.
Bots? again no need for me to worry.
I have a lot of experience writing bots and reverse engineering online games.
I know what makes me give up
MMOs just feel like a struggle for all the wrong reasons
you're working to prevent people from losing fun because of others, rather than focusing on making the game more fun
I think that depends on the developer.
These things are not so challenging to tackle.
With a little creativity it can be solved.
i'm not really sure if there are any exceptions to that, i've seen the same problem in every mmo/online game
if you showed me a 3d space mmo i'd be worried
i mean capital Three D
i am relieved it's 2D
An anti-cheat is over kill and underprotective to keeping out cheaters, because someone like me can just write a driver, and sign it. I rather build a game that is built correctly, fully server authority.
As it is right now, I have full state synchronization, and client has responsive server prediction, with reconciliation.
So there is no problem for the individual player, and the would be cheater has nothing he can do.
If someone were to make a packet based radar, then for my game everything that someone could see, they will see. I make anything "cheatable" instead a feature.
and now you just have to finish making the rest of the game
and make it attractive enough to build a playerbase
and keep it updated with fresh content
on the brighter side you have the precious experience
even if everything fails and you burn out
One of my recent projects was to reverse engineer a game called Albion Online, and I was able to find an exploit where a teleportation system in their game allowed players to send the amount of money it costed them to teleport. So by negatively adjusting this value, I was able to generate infinite money.
I always say it, people who employ anti-cheats like EAC and wash their hands are just lazy developers.
yeah but they still ended up making a game that found its' audience
That's true.
and i think that's way more important than everything else
That is also true.
Well if you're paying for it it's a job, and job postings don't go here, #πβcode-of-conduct
Aside from that, ask an actual question in the chat
its not actually a job but you are right sorry
i just need fix my issue
i so tired about it :/
Right so to begin it's usually a good idea to actually ask a question
i trying but its not working :/
What?
Right that isn't very helpful at all
In the editor I have a component variable and trying to assign a GameObject to it, the editor lets me select the GO, but then says it is a mismatched type. Is this an issue with the editor, or is GameObjet not of Component type?
Well I guess either way it is an issue with the editor, but is it of type Component?
I tried to use Object, but the editor only is allowing me to assign GameObjects to it.
And I know for a fact Component is of type Object
Indeed, but I should be able to select other things then GO for a variable of type Object and I can't
Correction I can drag them in, but the editor selector only shows GO
Yeah the editor just sucks still, no new news I guess.
I tend to avoid scriptable objects. Basically there's an editor callback that gets called right before a build compilation starts. The code runs on my network manager script. It loops through all scene objects and looks for my generic network entity class. If it finds them, it tags those scripts with a "SceneID" starting from 0 and iterates with every class it finds
I think it works pretty well
but yeah thats how I ended up doing it
Sorry - I lost the thread, but then I realized I replied to the wrong person. π
ScriptableObjects are life, though. Looping through all scene objects looking for a class seems like a lot of work for a singleton/DDOL
(Not for your problem though)
Yeah I just realized we never had a conversation together. I thought you were a different guy I talked to yesterday
Why aren't you just tracking the object (or Guid of the object) on both server and client? Why do you need to loop through all scene objects to find it? That's going to be .. uh.. really expensive
I only need to do it for pre-placed scene objects. Awake() doesn't get called in the same order on all objects if you change computers or something like that
They get tagged through the editor. It just places a read-only value on the component 0,1,2,3,4...
and its only before an actual build
Hm.. I read your original question 3 times and theres something about it I'm not understand.. could you explain again?
Why not use a fixed Guid value for it as a const..?
You mean like a guid string?
no, like a guid π
like that
that's maybe not a great example without more context but.. i don't fully understand your question yet
Because when a remote client connects to the server, the server has to send a list of SceneIDs and then the networkID of the object after that. The client can lookup the scene ID, and use the networkID to create a remote object on his end
so that they both know they're talking about the same object
GUIDs are basically strings
Guids are basically Guids π
If you send a GUID over a network, you send it as a string
They can be fixed if you want them to be
maybe it's better i ask here:
i would like to make a buff/debuff system. lets say i have 3 status effects, slow, poison and fatigue for example. i want the system to be able to take any status effects and combine into one 'buff/debuff'. i could make a script everytime with UnitEvents but imagine i'm making hundreds of these
Well, I mean, not necessarily - you said you were doing a custom implementation.. so why not encode it using something like ProtoBuf or MessagePack?
(I use Guids extensively through my code)
Yes but you get so much out of it.. low/no collisions, you don't need to manage sequences (as you might with ints), they have great equality checking, are actually pretty fast and lightweight, etc
No collisions with my code π
For things that are fundamentally some sort of ID where you need to know and sync and reference them - Guids are great
i'd appreciate any nudge in the general direction. i'm aware of ScriptableObjects and UnityEvents but the part I don't understand is combing the effects into one 'instance/object' effeciently
It wouldn't make sense to send a c# GUID over a network
Why not? I do it all the time?
I compress it into a byte[] first obviously, but I didn't write that (I use MessagePack for that)
I think guids have a bad rap. π
Because it allocates garbage
you don't want to be sending tons of strings every tick
to communicate with an object
I don't send strings......
I send guids. π I'm sorry if that's coming off as standoffish, heh.. But basically, I don't worry about the serialization and deserialization of things - that's what protobuf and messagepack and json.net and system.text.json are for - people smarter than me are thinking about these things and working on them.. there's no chance in heck I would try to do better than their implementations
But even so, Guids are pretty tiny when packed.. like .. a few bytes? maybe
they're not strings, they're Guids - and while you can create a Guid from a string, that's where the similarity ends - it's a series of bytes and only converting it into a string before you send it across the wire is going to .. use all that allocation
Ok so I've never used GUIDs before. So they're a 128 bit integer
regular integers are 32 bits
aye
that's not really a meaningful size difference.. but .. still, yes, it's bigger but you get a lot more functionality out of the guid
bandwidth increases exponentially per player joined
ints - if you have a sequence or id, you have to worry about collisions, who's generating the key (probably a server, but what if it's peer to peer) etc
if you've got 300 players in a server, it matters
even then, I can compress my IDs to be less than 32 bits
300 players sending 16 bytes 20 times per second is 100k/sec - and that seems pretty reasonable to me
I'm high right now, so go ahead and give me a second to compute some things
at the end of the day you can approach problems like this however you want, but to be productive and effective you should try to use solutions that many people have already created instead of trying to do better than them by yourself.. it's also probably just not a super great use of your own time.. π
https://pastebin.com/93UP5ey1 this is one "battle state" in my game - look at all those guids! all those strings! omg it's going to be huge!
it's 900 bytes
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
I can send it every turn (games are like 200 turns) for 1000 simultaneous players on one alpine linux container of the smallest size
optimizing your network use is probably not as productive as .. building games π
optimize after
if anything
no point optimizing this if its only like 1% of the network overhead
900 bytes is pretty small, if you were that worried about size you would not be using json in the first place
You don't want unity for these kinds of things, probably. How I'd structure it, maybe (there's lots of correct answers here) is like so:
public class StatusEffect // not a MB
{
private List<SingleEffect> _effects { get; set; } = new();
public decimal GetEffectValue(EffectType type) => _effects.Where(x => x.Type == type).Sum(x => x.EffectAmount);
}
public class SingleEffect
{
public EffectType Type { get; set; } = EffectType.None;
public decimal EffectAmount { get; set; } = 0;
}
public enum EffectType
{
Poison,
CripplingOldAge,
}
you really want to cache that value
I'm not - I was responding to the OP
and not linq it everytime thou
if GetEffectValue needs to be cheap would just build and maintain a dictionary for it
public class StatusEffect // not a MB
{
private List<SingleEffect> _effects { get; set; } = new();
private Dictionary<EffectType, decimal> _cache {get; set;} = new();
public decimal GetEffectValue(EffectType type) => _cache[type] ?? _cache[type] : 0;
public void AddEffect(EffectType type, decimal val) _cache[type] = val;
public void RemoveEffect(EffectType type) _cache[type] = 0;
}
HAPPY?
π
not an interface /sad
I'm gonna punch someone. π
π
@misty gladeEach player needs a few fields.
NetworkID: 32 bits (4 bytes)
PositionXYZ: 96 bits (12 bytes)
RotationXYZW: 128 bits (16 bytes)
32 Bytes per player + headers
Each player needs to see every player on the map
300 players per server
300 players * 32 bytes (one player state) = 9600 byte per player PER tick.
You need to send this ^ (9600 bytes of info) to every player every tick.
9600 * 300 = 2,880,000 bytes per tick
30 ticks per second (30hz simulation rate) = 86,400,000 bytes per second
86,400,000 bytes per second = 0.6912 gigabit per second
this ^ is not premature optimization.
someone is undefined
this is more a
why are you syncing every player
Ok so .. hang on, you are thinking that you need to send location information to 300 players 30 times per second? ....
and not just within their local space
you can sync players that are local to them faster
That's my initial point. He's sending 128 bit player IDs
then the ones further away
and that's not good practice
ok
look at whats causing the biggest overhead
not micro optimisations
like if you want a real answer
think about it this way
even if you change it to a 1byte id
its not that big of a deal compared to sending the data for basically no reason
are they gonna even render a person that far away
Would you personally use C# GUID values for tagging network IDs?
They aren't even collision proof
you have to do your own checking
You said yourself you're only sending it once.. so... why do you care about optimizing it..?
What if you generate two GUIDs and they're the same value
what happens
if a gamma ray event hits
your memory
and swaps your id from 0 to 1
heh
guid collision probability is one in 2ΒΉΒ²Β²
what he's trying to say is that the chance of guids colliding is infintesimally close to 0
you are asking questions that basically dont' matter
Iterating from 0 collision probaility: 0%
in theory, but you only have 32 bits, so you'll collide much sooner than with a guid
its capped at 300 thou
it doesn't matter what you use
is what i'm saying
you can use incremental ints
or shorts
or w/e you want
it really doesn't matter right now
π
this is premature optimisation
Ok
I mean.. look, people are here to help.. at the end of the day you can choose whatever solution makes sense for you and your game, but... I think reinventing solutions to problems is.. probably not a super great use of your development time
If you want to spend a lot of time optimizing or caching IDs so they don't collide, map to permanent IDs, etc etc - great, do it.. but.. people are saying that it's really not necessary for the first 95% of a project's development
probably maybe not even ever
main network optimisations happen on the bigger picture usually
like if you want to get into the nitty gritty of it
create a custom packer
and chop off float precision
Yes that is generally how the industry does it
The JSON thing I posted above.. I wrote this serilog sink to send that entire data packet to the server to help me during a particularly rough debugging time.. It sends this packet of 1k every single turn for 2 players - I saved the server copy, player A copy, player B copy, thinking I would just turn this off after a few days of dev.. Ended up being the best fucking feature ever, and not even using very much data at all.
first step should be designing a game that can by synced realistically assuming normal-effort optimization and premade solutions
That's my data stream for a game - looks super noisy, but all the data I need to debug is there, and it just barely even moves the networking needle at all, even for 1000 bots playing instantly
optimization as a whole discipline is way too focused on by developers.. more important is getting shit done
hobbyist developers
this is hard to get through to people usually
aye
slight inefficiency is better then dropped game project
so many people worry about it before they even understand the basics
best to write jsut really easy to read code. even if you have to change it later its better this way
this exact same conversation template occurs every week/day
there is always more work to do in games, so decide what done enough is get it there and move on
you can use FindObjectByName and still sell 500k units
i am agaisnt find object by name not for perf reasons though
it makes things fragile to change
if it saves 4 weeks of dev time two months before launch...
Guys can I just share some .. relief? I just finished this latest feature in my battle game where the game designer designed 65 different abilities.. holy crap.
DONT OPEN THE +
am working with a designer that always goes overboard on features and never does things within limitations. then says the team at his old workplace could do it
problem is we are like 5 devs on a project not 50 like his old job
heh.. having a good game designer who .. you know, respects what's difficult and what isn't is amazing
depends on if the game designer understands the dev process
then i worked with other ones that are just amazing, they work within the limtations
i've seen worse honestly
people who do that kind of thing are in grave danger of being punched in the face
2000+ lines for a single method
and are fine working out sacrfices with art and dev to make things easier for everyone
ouch
This one was complicated because these abilities all interact in .. really difficult (but honestly fun as a developer) ways.. like... one prevents damage entirely, another reverses the target of the attacks, another makes your guys have to go to 1hp before they can be killed, another makes friendly crits hit yourself, etc
just the interactions are all .. wild to handle properly in code
there is code with millions of lines that has only a single class
ahh yes -hides my first game in BASIC
yeah had a project with a class that was 60kloc
its called C code
scary part was it was C#
RIP
ide just hated that one
i think method length is no differentiator of good/bad code
i'm doing exactly that...but maybe not with statics
each modifier is added to create a skill
i'm probably going to developer hell but i love singletons and static methods
yeah buffs debuffs and stuff i have mostly done as 1 class per effect type thing that all implement a common interface
if it works go for it
works for me.. i just like the syntax of not having to FindObjectOfType<> or pass around references everywhere in my game
have worked in a few singleton heavy proejcts and its fine. would be hard to add unit testing but otherwise fine
its totally fine if your project is well scoped
I wanna send a network message? NetworkManager.SendMessage() I wanna play a sound effect? AudioManager.PlayOneShot(type)
normally i outside of unity i would do DI by passing refs down the stack. but its much harder in unity when you do not really have 1 well defined entry point
its not great for refactoring or working in teams
I wanna mine bitcoin? AdManager.MineBitCoin(); /s
though i did end up making a basic depednecy injection system for unity i use at work now
Passing around refs is how I first started but man... it got so heavy
got all that crap in mine
not a fan of unity's interfaces for this btw
i wish
this exists
just out of the box
i'm so use to ASP that it pisses me off
there isn't a dependency injection system
Its all fun and games until the designer asked for number 66 and you have to dig through the code and make sure you don't break anything else while trying to add it π
found a lot of out of the box ones like zenject add too much complexity
so i made one that suits needs of my workplace
it should but.. I sorta understand why it's taken so long.. unity is it's own ecosystem, changes are hard, slow, take years.. DI doesn't seem to have become as important as it is until .. i dunno, recently
nice
You have no idea π
i hope they never add a DI framework
DI has been around for about 4 years thou
atleast main stream ASP
might've been even earlier
I think I have a pretty good idea. And it isn't pretty xD
but thats when i started really working with it
wait nvm
covid
make that 7 years
It's actually more that these abilities all often add status effects to the game.. my "process one attack" method which literally should be one line of code:
public void Attack(GridItem source, Player target)
{
target.CurrentHP -= source.Damage;
}
is like... 500 lines
might have to build my own...
it doesn't have to be
you can make the other stuff process it
it's hard to explain easily without going deep dive into the game mechanics.. but.. i'm happy with this approach
it's not just damage though
fair enough
its not that bad to do it, really its a system that lets thigns register as a Dependecy, then systems that need stuff injected put the Inject attribute on fields and call DI.Inject(this); in awake and it does the rest
sometimes it changes targets, sometimes guys don't attack, sometimes they do "trample" damage (excess to the next target) etc etc etc
yeah i've just never considered building one
it's... complicated. π
nice
This made me think that it would be cool to write a code gen for this that generates tests which tests all the status effects and make sure they all interact properly. I imagine it would either be really fun to write or a living hell lol
Wait, does unity not serialize MonoBehavior that have the partial keywords?
This is what keeps me up at night tbh
65 characters, each with a unique ability, 3 characters on a team, turn based game... the interactions between the abilities is truly wild.. I just have to hope that I have the programmer chops that my bugs are small and rare.. So far so good
nice good luck on the beta test
pretty sure it will work on MB's that use partial as long as one of them uses the same file name and class name
I have "bots" that can generate random moves and they can happily play against each other, but as far as testing "correctness", that's the hard part. The only thing I get out of bots is load testing and crash durability.
this is looking really great
(which is something)
Thanks P
It's .. finally starting to get some lipstick. Still needs a lot but all the abilities are in the game.. they're pretty cool too
x65
crew art is looking good .. battle game art needs a lot of work still but we'll get there
Oh yeah it is, just for some reason it wasn't, but restarted unity and it is working fine now.
Unity does weird things to me if I don't restart it daily btw.. like hangs for like 10sec when doing things that should be instant on startup.. never seen serialization with partial class issues, that's a new one
but I don't have problems with partials, i use them everywhere too
(i only serialize a few key data points in that singleton but it has always seemed to work fine across partials)
yeah i turn my work machine off every night. get less weird things as a result of launching it fresh every day
Yeah, 2022.2b has been extremely solid and I am not getting random errors like before, but there are still some weird things now and then.
it's reassuring you are the kind of maniac that uses backticks in filenames
i'm a maniac in many other less exciting ways
did you ever consider the sane and humble period
i did, briefly, then had my morning coffee
ha
soon! this week or next, I think, actually
once we finish stamping some particle effects and final art into battle game and idle game, we have one more content pass and then some strategy on community management and so on.. then we'll start inviting friend and fam
everyone in this chan is fam, fam
my favorite piece of code is my BigDecimal class. it literally has 2 data points and is still like a thousand lines of code
public sealed class BigDecimal : IEquatable<BigDecimal>
{
public decimal Mantissa { get; set; }
public int Exponent { get; set; }
// how hard could the rest of this be?
// ... 1000 lines later ...
// kill me
}
oh god looking over this class is making me laugh out loud
about my experience with this
i left all kinds of passive aggressive comments to future-me
the result of random bughunting afternoons
hahahahahahhaha
that probably shouldn't make it to production
O.o
jesus i have stuff in here that is honestly just magic
square rooting large numbers, for example
reminds me of the quake's fast inverse square root
i have this code to be able to press on an object with my mouse and be able to drag it with my mouse and move it from place to place but there is one problem, on a different fps, its seems laggy to move an object, is there is a way to like, keep the code functioning smoothly even when the fps drops down ? i am not sure how to say it but i hope u get what i mean lol
this is one of my planned tattoos, btw
yes, don't do this in Update, do it in IDragHandler::OnDrag
Your big clue is "Update is called once per frame" π
do that and implement all those methods, and only move it around when you need to instead of every frame
its more a why is fps dropping so hard
oh lol yeah
that its lagging?
Yeah, I feel like the making the drag not choppy is kind of trying to fix the wrong problem...
Yeah actually my fix won't solve his choppy problem since his code actually looks fine?
I think OP might have something else going on elsewhere in his codebase
Besides the Camera.main every frame, yeah the code looks fine.
Probably time to use the Profiler to figure out what is hurting your FPS @regal olive instead of trying to change the drag code (which again, looks fine)
I wonder if the object he's moving is interacting with the ray in a goofy way?
like one frame it moves it, then the ray hits it, so it tries to move it to a different location every tick
but that still shouldn't be an issue since it'd only happen once per update and nothing in there is too expensive
(i mean, it wouldn't work properly but that's a separate issue)
its not a problem with the game but like, i can assume that some players would have a weak PC running the game on so in THEIR case, they might get a drop in fps so i am making sure to keep the interaction smooth as possible in every one case
theme of the evening and really every day: don't optimize too early
just get it working, optimize when you're in the last 5% of your game
1: make it work
2: make it correct
3: make it beautiful
4 - 58,392: other things
58,393: optimize
I agree, but also I dislike that saying as it implies you should just write really sloppy code. Then you are going to run in to an issue of a death by a 1000 cuts. And also will be hard to optimize. But I agree with the meaning of not putting in extra effort to optimize before you need to.
Yeah, I mean, that's what #3 is for
Yeah, I was specifically referring to the saying
I'm definitely never of the opinion that sloppy is ok early.. Like, I would much rather spend (too much) time looking at the structure and cleanliness of code early on instead of profiling and optimization.
Making it "beautiful" (ie, simple, clear, easy to understand even if you're not familiar with the codebase) has saved my neck sooo many times when I come back to a dusty area of the codebase and can't remember wtf I was thinking when I wrote it
Basically, if the dragging is lagging, the whole gaming will be sagging
Same! Putting in a little extra time and effort when designing something to make it nice can save you so much time later on!
So it looks like these keeps not compiling correctly or something. On unity restart it isn't seeing the script, and if it does it doesn't always update on save. AKA it is broken.
If I put everything in one script it stops having these issues.
Strange. What specifically are you having trouble with?
(awful timing btw I was 8 seconds away from leaving the computer after an amazing day of killing bugs) π
-10 bugs +?? bugs
I had an array of structs on one of the partials, and changed a variable name, the name didn't update but unity would compile changes on other scripts. Then on restart of unity it was saying the script was missing ish(grayed out without any variables, but not fully missing). No errors showed up. I just put everything in one file again.
so many bugs I can't even count them π
@velvet rock I actually am just seeing that I lied to you previously - i don't have any partial classes that are storing serialized values in the partial class - only in the main class
You can't spell unity without bugs
and my quick test shows that it doesn't work at all for me
oops wait, I lied, i didn't save my file
for (var programmer in Team.Programmers)
{
bugs += programmer.FixBug();
}
public class Programmer;
private int FixBug()
{
return Random.Range(-100, 100);
}
Yeah, coders are second class citizens in unity's eyes. We are decades behind actual C# features and the features we do have aren't actually support XD
eh, at the same time, I'm happy for a lot of the magic
but i dont know why they do so much magic i guess
like .. we wrestle with weird things but i mean, also at the same time we can create games
my project is ... 120k lines of code
i'm still waiting on ECS to be released properly
there's no chance in hell i would have been able to get this far if i didn't have unity
with 2D support
and you never will stop waiting
ikr
i'm definitely not going to need ECS for anything i make in the next 5 years.. i look at shit like sakurabunny and then my own project, then cry
I know C++ and unreal is nice, just back 5 years ago I was like, oh unity will keep up I am sure, and C# is alot nicer. eh hindsight is 20/20
i'm sure you guys have seen that video floating around? "what i did in 2022" or whatever
They've been fiercely working on coding features constantly. While they've been behind, it's not as if they haven't been working their asses off.
Compare this to anything else that is actually second-classβlike audioβand you'll note how nonsense this take is
No audio is third class XD
Evolution of technologies. .net 6.0 is a god send for us .net developers, and the crossplatform support that comes with it. Unity went with Mono because at the times amazing crossplatform support, but no one kept up fast enough with technology changes, and having to continue support for older platforms. Also don't get me wrong Unity has put in work, but they have had to work around a problematic system to begin with, and having to juggle updating old system and coming out with new systems to stay relevant isn't easy.
Unreal being all one system has helped them tremendously, and then the funding that comes with being the industry leader is allowing them to go above and beyond(like with the new auto generated LOD stuff that is just industry changing).
Also they didn't throw it away, they saw the limitations and decided to make a better solution that solved the problems from .net framework and .net core, which is what Mono tried to do.
they created like 4 .net versions
before now landing on .net 6/7
but that doesn't stop them from throwing away this too
.net standard wasn't even really a standalone version it was more a library anyway
that gave you all the interfaces you needed
but anyway the problem was never if .net standard was good or bad, or if .net 6/7 is better, its more about unity moving to standard then it being dropped lol
Yeah, there is a thread about them planning on moving to the new .net but from the sounds of it in a few years. Which hopefully will come with webGPU also.
@undone coral Revisiting our earlier conversation, because you did give me a lot to think about. I am considering transitioning to a API based master server. My dilemma rises from my spawner servers, which the master server will need to control. When a player joins, and needs a server to play on, the master server will communicate to a spawner server to have the game instance created. Do you have any idea how this could be done in this type of project? I'm trying to limit my overhead.
What's ECS
Entity Component System (part of the D.O.T.S tech stack) you can google it.
Ah it's part of dots
does anyone know how I can get a reference to an AnimationClip from an imported fbx model? I want to add it to an AnimatorController from code
Use a [SerializedField] to reference it, in the code
I want to do it in AssetPostprocessor
Then you'll have to look up how to load assets from file
I did, and after that I came here π
What have you tried so far?
I can get the path to the containing model asset, I can get names of individual clips inside of it, but I don't know how to use that information to get a reference. If I drag those clips into an animator manually I can click on the created states and on the clips in their Motion fields to see that unity highlights those clips in editor properly, references lead to the clips inside of the imported .fbx just like you would expect
I can also get the references inside of
void OnPostprocessAnimation(GameObject root, AnimationClip clip) {}
, however that AnimationClip exists only inside of that method and gets destroyed immediately after, so you can't use that reference to add it to an AnimationController, it'll be null
Store it in a separate variable?
it's a class, doesn't matter if you assign it to a variable, by the time you use it you'll get a message saying "AnimationClip has been destroyed but you're still trying to use it"
ScriptableObject maybe?
Though given it's a class it might be passed by reference thus still destroyed
yeah. I wonder what others do. without being able to get those references your only option is to always drag those from the imported models to a controller manually. every time you import something new that has animations
I don't know if you could somehow dupe it and detach the reference to the initial one, but then that it still has the reference to the actual thing in the file
if you mean the clip that you get in OnPostprocessAnimation I doubt that it references the original clip on disk at all, it seems to be a temporary thing that unity gives you to modify and then copy params from. Why else would it be destroyed after? If that's true it doesn't expose that reference to the real thing in code at all
yeah, I tried AssetDatabase.TryGetGUIDAndLocalFileIdentifier on that AnimationClip, it doesn't give you anything
Rip
I honestly have no idea
You'll just have to continue googling and hope you strike that gold on StackOverflow kek
yeah. internally (when you drag those animations from the project panel to the animator) it references those clips by file id. I could theoretically generate the yaml for the animation controller myself by reading those straight from the imported .fbx.meta π
How would I specify a ToString
Hi! I'm trying to set navMeshAgent position to the transform.position. I'm using navMeshAgent.nextPosition = transform.position. (updatePosition in navMeshAgent is obv disabled). This works well when the enemy is inside a navmesh, but when I try to move it outside the navmesh the navMesh position gets stuck in the edge of the navMesh where it is inside.
This creates a bunch of problems when the enemy or the player, for some reason, leave the navmesh area
I'm using navMeshComponents addon btw, and I generate an area around the player and, if the enemy is outside the player's area, around the enemy too.
Any help? Getting help with navMesh scripts seems impossible π¦ idk if everyone just abandoned it and is using something different, or no one uses it
If needed I can do a quick recording to show what's happening
I got so infuriated yesterday trying to simply link CommunityToolkit.MVVM in a Unity project
It took me hours of fiddling with runtime versions and combinations and manual copying of libraries
All because Unity isn't on a reasonably recent .NET/.NET Standard release
is a server a unity process? is it a windows or linux executable? if it's not a unity process, is every user backed by 1 thread in your server? a fiber, actor or other "message box" over evented io? or no threads actors or fibers?
disable the agent when it leaves the navigation area
this is probably the best way to do it
you can also read and write to these private fields
postprocessing the assets however does work. try searching grep.app
I solved it with a monobehaviour helper class. basically I'm adding a component at import and putting clips in a list on that component so that they go through serialization. then they can be referenced later and added to a controller
@undone coralThe game server is a unity process. The master server would be a ASP.NET API. The spawner server is currently a console application.
is it a windows or linux unity process?
and is it windowed?
and does each game server run many users? like dozens?
I can get the path to the containing
I need it to change navMesh
and to generate its own navmesh
in theory, I made a script that when the enemy leaves a navmesh (e.g. the player moves and the navmesh generated around him moves) he generate its own navmesh
or, say, a knockback moves it outside the navmesh
that's exactly what I'm trying to do
detecting if the navMeshAgent is outside the player's navMesh, if so generating its own navMesh
problem is, I can't even detect if he's outside the navMesh area since the agent gets stuck at the area border
what do you mean, generate its own navmesh?
navmeshes are global and shared by all agents of the same size. what is your game?
I guess this is an advanced question. I am trying to use a gameObject with a box collider to change the animation of the player when the player enters the box collider. I have tried several different methods, but none of them are working to change the animation even though the Debug.Log is outputting when testing
It's a scripting issue. I have the animation set up properly, but the script is not triggering properly
You said the code is running
if the code is running, then you're not doing the animation bit properly
But something is not being accessed properly. The animation is configured properly
It's just one bool that I am trying to flip
well without any details it's not really possible to help
I have a box collider with a script "AnimationTrigger' that when the play enters the box collider it changes the animation.
`public class AnimationTrigger : MonoBehaviour
{
public GameObject player;
void OnTriggerEnter(Collider other)
{
player.GetComponent<Animator>().SetBool("isJump", false);
Debug.Log("Change Animation");
}
}`
great so - if this code is running, it's a problem with your animator state machine
which is an #πβanimation issue
or you just referenced the wrong player object
I am getting this error "Animator is not playing an AnimatorController " now
that means you're manipulating a decativated or disabled Animator
... How is it deactivated? It's working until the player collides with the box collider
you tell me, I can't see your probject
whatever object you referenced there is not active, or the animator is disabled, OR IT'S A PREFAB NOT IN THE SCENE
something like that
Dude. I literally have no idea
well start looking around
The player is in the scene
this is really #π»βcode-beginner / #archived-code-general stuff tbh
Yeah betting on "player variable refers to a prefab" too
good for the player. What about the object you actually referenced here?
Yes, it spawns at the start of the scene
like why do you even have a player variable here? Shouldn't you just be grabbing the component from other? Isn't other supposed to be the player, since the player is entering this trigger?
so you're trying to animate your prefab
not the actual player
obviously it won't work
There's a reason you get a reference to the other object here
So the player is at the start of the scene. When play is clicked, a buildings start spawning that the player is running across. I have a box collider that is set just above the top of the building so it will trigger the animation to change
Yeah we're past all this
I already noted what your problem is
and how to fix it
you don't need to repeat this
You said I was trying to animate a prefab, but I'm not
Let me repeat this
You are animating a prefab
Instantiating it when the game starts won't make all the other scripts reference the instance automatically!
Oh wait, I see what you're saying
I got it working. Thank you
How can i combine textures into one at runtime? Im loading some png files and then should combine them into one texture also ordering is important for me. Any tips how can i do this?
Are you trying to make a Sprite Atlas?
https://docs.unity3d.com/Manual/class-SpriteAtlas.html
not really. I need combine textures into one at runtime
You can use Graphics.CopyTexture, not sure really if this is what you want.
why?
im using one material for different meshes with different tiling and also texture files can be changed at runtime
yes but why? what is the gameplay?
minecraft
hmm
[SerializeField] Transform target;
private void Start()
{
target = parent.GetTarget();
}
GetTarget returns the [SerializeField] Transform target; of the Parents class and it changes...should this code work and keep the target in it correctly as its a reference to the Parents target?
was running into bugs so I had it call target = parent.GetTarget(); each time before running the code that uses target...and it doesn't have issues now
I feel this may be a slightly more advanced question but π€·
this is definitely a #π»βcode-beginner question.
The answer is we have no idea what you mean. References are references. Transforms are Transforms, and without further context it's hard to say anything
Each navmesh is generated locally
around an entity
(It's actually a navmeshsurface, not a plain navmesh, but the logic on the navMeshAgent is basically the same))
Learn how to bake a NavMesh on a small portion of your level. This allows much faster baking of NavMeshes on large procedural worlds, or on very large worlds. We do this by specifying a volume around the player and use the NavMeshBuilder class to collect the relevant sources and update a registered NavMeshData.
If you are taking this concept a...
Like that
It's a survival in a 3d procedurally-generated world, that's why it's not that easy to bake a navMesh agent in it
it would take way too much time to bake it every time a chunk spawns, or worst, every time I destroy something
or add something
Hi I need to copy location of object I am colliding with.
I have really weird outcomes.
Code:
//copy use euler angles to copy position and rotation
col.transform.eulerAngles = gameObject.transform.localEulerAngles;
//rotate by 90 degrees on X axis
col.transform.Rotate(90, 0, 0);
Result:
Its in Z dimension position a bit more far
even without 90 degrees rotation I am giving it
I see I need to get center of the empty object how I can do it?
Anyone knows how to force a navMeshAgent position to the object's position?
or better, how to make a navmeshagent work with two or more navmeshes colliding with eachother
like in that case, where the navMeshAgent is bound to the left navMesh and will not jump to the right one, not even with a set of nextPosition or when the agent is in the right navMesh
if you don't get a response here you can also ake on #π€βai-navigation
okay, thanks π
gonna check that there, hoped this channel would've given me more answers since it's more a code-related question
Json format
Hi all mates devs! I want to create functionality for** screen image recognition**, just on a flat screen, nothing related to AR or VR, and I only find info on the web and this forum related to AR, but the purpose is just to detect an image when it appears on the screen, any help?
The idea is to manually introduce a sprite in a program, and when this sprite appears on the screen, do something
Screen doesnβt really differ from non-screen, you can just use render to texture functionality in cameras to get image of the screen. Image recognition it self I donβt have experience with, but just googling c# image recognition will give tons of resultsβ¦ finding something which isnβt cloud solution and is good will be the hard part
why would you need image recognition to detect if it's on screen? e.g if you create a cube in the game, you can check if the cube is being rendered directly, you don't need to start processing the final rendered output
Iβm guessing βmanually introducedβ means that player draws the sprite or something and when itβs mario with 90% probability it will transform into mario etc.
probably correct but that's still a lot of assumptions about the original question
True π
i've waited like a day, so if anyone has any info about the #π±οΈβinput-system thing i mentioned would be nice to know (trying to avoid cross posting)
Does anyone know if there is an API for changing these 2 values? Can't seem to find it.
They're generally EditorPrefs
Or in a config file in projectsettings
ProjectSettings/PackageManagerSettings.asset
ugh look at those scopes. unitask, unirx, naughtyattributes, deform... this guy fucks
okay so
if you want to carve away at a navmesh, create an obstacle
i agree that you can't easily expand a navmesh. when you need more control you basically have to use aron granberg's a* and modify it to only cast for navmesh the newly generated pieces. in his framework you will be able to append navmeshes together
that's no longer entirely true with navmeshcomponents
it sounds like the user knows how to expand it but it isn't expanding "smartly" it seems to consider the entire region of geometry
instead of a difference of geometry
but i'm not sure
it's really hard tos ay. the user is doing something that makes no sense right now π¦
yeah in their position I would probably try building the navmesh async in tiles around the player
but I don't know, I haven't done anything like that
I'm doing that!
Async is still blocking the game, idk why
wait..
In the end I asked a similar question in the a.i. channel and created a thread, I explain the problem there in a mode detailed way... If you're interested in helping (I'd be very glad <3) you can see more info there, I explained why i'm doing everything...
tl:dr; the map is huge and baking the whole world is out of discussion, even with async; so I'm trying to build a navMesh in an area around the player and do the same for the entities that are outside that area, but navMeshAgents doesn't work well with more than one navMesh in the same spot
Hey I have a 2d game with a grid and I have a List of a few tiles (gameobjects with sprite renderer) in my script and the script places these objects in my scene with Instantiate, so far so good but now I want to add new tiles to that list of tiles that already exist in the list but rotated 90 degrees. What would be the best way to do so?
can you not just instantiate them in a rotated fashion instead of adding more variations to the list?
I tried that but its not quit working currently I have a class Tile:
public class Tile
{
public bool isCollapsed = false;
public List<int> options = new List<int> {0,1,2,3,4};
public Vector2 pos;
public TilePrefab prefab;
}
[System.Serializable]
public class TilePrefab
{
public GameObject tile;
public Quaternion rotation;
public List<int> edges;
}
and then I have this function to create the new Tiles:
public void generateTileSet()
{
int count = baseTiles.Count;
for (int i = 0; i < count; i++)
{
//baseTiles.Add(new TilePrefab { tile = baseTiles[i].tile, edges = baseTiles[i].edges });
for (int j = 0; j < 4; j++)
{
List<int> oldEdges = new List<int>(baseTiles[i].edges);
List<int> newEdges = new List<int>();
Quaternion rotation = new Quaternion(0, 0, -90 * j, 0);
//Debug.Log("Rotation = " + rotation.z);
for (int k = 0; k < 4; k++)
{
//newTile.edges[k] = (oldEdges[(k + 1*(j)) % 4]);
newEdges.Add((oldEdges[(k + 1 * (j + 1)) % 4]));
}
for (int k = 0; k < 4; k++)
{
if(oldEdges[k] != newEdges[k])
{
//Debug.LogError("Added new tile");
baseTiles.Add(new TilePrefab { tile = baseTiles[i].tile, edges = newEdges , rotation = rotation});
//Debug.Log("Rotation = " + baseTiles[^1].rotation.z);
break;
}
}
}
}
for (int i = 0; i < baseTiles.Count; i++)
{
optionsCount.Add(i);
}
}
and then I Instantiate them in another function like this
GameObject tile = Instantiate(baseTiles[index].tile, new Vector3(pos.x, pos.y, 0), baseTiles[index].rotation, this.transform);
But first of all the rotation does not seem to get saved correctly in the baseTiles list and when I instantiate them they also have a wrong rotation
that's not how quaternions work
I figured
you want to be using euler angles, so you can use Quaternion.Euler(0f, 0f, -90f * j) instead
and I know this log is commented out, but accessing individual elements of the quaternion is also not what you want
you want to instead use rotation.eulerAngles.z for example
if you were to want access to a specific value from it
thanks alot mate, I try to fix up the code (:
@untold lark Use the forums for job or collaboration posts. #πβcode-of-conduct
Ok, i'm sorry
because unlike the navmesh bake, navmesh source gathering routine is not async
but you can write your own gathering routine and make it async
What exactly is a navmeshbuildsource?
because in the docs there's only written:
"Description
The input to the NavMesh builder is a list of NavMesh build sources."
And this doesn't help, at all
I don't understand if it's the area itself, or the list of objects that are in the navmesh area
maybe we should use the thread in the ai channel π
in short, sources describe the geometry that will be used to create the navmesh
https://docs.unity3d.com/ScriptReference/AI.NavMeshBuildSource.html
You better just take a look at the sources, since you'll probably need to expand the navmesh components anyway
yeah but what exactly is a "source"? I get that that's an input used to build the navmesh
what does it represents?
the objects above the navMesh that I want to get?
No, the navmesh is baked by finding flat areas that a character could walk on top of
based on your settings it can either use the world geometry (mesh renderers) for that, or physics objects
what if I don't want to use neither?
since it needs to go into the 'build nav mesh' function, it's encapsulated as a NavMeshBuildSource
Well, how are you going to make sure your characters can't walk through buildings or whatever if they're not part of the navmesh?
since I have a lot of objects per chunk I could bake just the terrain (to have a nice flat navmesh) and then use the navMesh obstacle with the "carve" parameter set to true
I noticed that if I build the objstacles with physics or meshes it's more accurate but it actually takes a lot of time
and tries to build navmeshes above trees, for example
possibly. Or like I suggested in the thread, make the collecting build sources part of your procgen so you already have all the objects that need to go into the navmesh building function
π I'd like to do that but I still don't get what exactly a source is, so I can't collect them...
I know it's something needed to build th enavmesh
I still don't know anything about it
I don't know how I should initialize it, for example
That's a nice initialization of a source shaped in a box
you just create one with new NavMeshBuildSource() and then
but still, what is a source? How should I choose the transform, the size etc.
add the necessary data
yeah man ahahah
I'm not getting what the necessary data is
that's my problem
for example
for terrain you need to set sourceObject according to that manual page
should I do a loop around objects on my terrain and creare a source per object, sized as the object?
and set Shape to NavMeshBuildSourceShape.Terrain
and probably you need to set the transform matrix as they do in the example
just prototype it and try it out
and the final result is... a plain navmesh? with no obstructions?
if I use just the terrain as a source
right?
should be
gonna try it out..
So, other sources will be the blocking objects?
yes
mmmh... so the source is both the terrain AND the objects in it
that's why it's a list of sources
everything that should go into calculating the navmesh
uhm... I'll try a test script, let's see what I can do
Thanks btw, really thanks
that's at least something to start with
i've been blocked for days..
making games is hard ^tm
ahah yeah but i didn't expect the a.i. system to be THAT hard
That's definitely not working... If I create only one terrain source it should create a plain navMesh square (without any obstacles above it), right?
I created it like that, this is used instead of CollectSources. Slightly under that there's the updateNavMeshDataAsync... Well, no navmesh is created
I also tried to set transform to local transform (That script is on the player), it still doesn't work, tried to set the shape to Mesh (the terrain is actually a mesh, it's not a normal Unity terrain), didn't change anything
what's 'terrain' there?
Here, in the test scene, it's a plane
with a navmeshsurface
nothing more, for now
looks like it's the component?
should be the terrain data object
wait it's not a terrain?
You're building your own navmesh from code, so you don't need a NavMeshSurface
can't use unity terrains to do a procedural world
okay, already tried that, but i'm gonna try again
the sourceObject should be the mesh then?
the mesh component
you can also run CollectSources and check in your IDE what it returns
looks like it should be the Mesh itself
not the component
okk
hum.... something really weird happened
I'm getting the mesh from the meshFilter
When I execute that code, the scene view doesn't show a navMesh but shows the borders of the mesh:
actually it shows the mesh itself
the green lines have never been there
and the plane mesh becomes a plane instance in the plane's mesh filter
use .sharedMesh instead of .mesh
Did that, nothing happened
Although.. the manual does mention mesh.isReadable needs to be true
so make sure it is
it is
it would give an error
I've read that many times, for local objects
(like, "Sword mesh is not readable", or something like that)
With shared mesh it doesn't show the green lines, but the mesh is still not there
the reason it became an instance is that when you access MeshFilter.mesh it creates a copy of the mesh
it's also one of the default unity resource (the plane mesh) so it's readable by default
yes, but I'm now using a sharedMesh
not anymore an instance
but still, no navMesh shown
okay keep experimenting
https://docs.unity3d.com/ScriptReference/AI.NavMeshEditorHelpers.DrawBuildDebug.html
this might also help
areas are part of the navigation system; you can block areas for certain agents for instance
"Describes the area type of the NavMesh surface for this object.". I'm guessing that's the.. agent type area?
Ahh yes, yes
right ,thanks
so 0 is walkable, I guess 0 is the defalt area but I'm gonna set that, just to be sure
so, if I want to carve an object to the mesh, I'd have to get a list of, for example, the trees, create a source box for each one, set their area to 1 (not walkable) and then build it?
(build the whole navmesh)
that could work, but if it's a tall box it'll carve a hole in the navmesh at the bottom anyway
ok, can't get the basic mesh to work. I guess I'm doing something wrong with the parameters somewhere. I also tried to set the component to the MeshFilter(as the docs says, referred to the NavMeshBuildSource.component:
"When build sources are obtained using NavMeshBuilder.CollectSources, this value typically refers to a mesh or collider component - however for shared meshes it will be null. See Also: MeshFilter.sharedMesh".) It still doesn't work, but I guess I understood what a source is and what my objective is, so those are huge steps towards the problem
That is, currently, the code
I'm still not telling anywhere which agent I'm using. Should I be creating it "manually", by extruding blocking objects bounds? Or am I missing something?
yeah you're getting the buildsettings from 'navMeshSurface' but I don't know what they are
that debug settings link I shared had some example code
oh right, forgot about that sorry
also the bounds may be wrong? I don't know
you could also try calling CollectSources on the transform with your mesh and inspecting what's in the 'results' list
if it works with that function, see what's different from what you're giving it
it WORKS! cool!
bounds in the build method were wrong
if I increase the bounds, the area is bigger, until all the plane is a navmesh.. Then what's the source size used for?
it doesn't matter if I use a size of 100 or 1, it will still use the localBounds in the build method
nevermind, they work
maybe source size is not used for mesh sources, I don't know. But Bounds is the total area the navmesh will be generated for, not per object
That's right, it's in the docs
"Used only for the primitive shapes: Sphere, Capsule, Box."
but now I've got a problem: since the area is defined by localBounds and the mesh size is simply added to full size, I can't subdivide the map in chunks
I'm still limited to an area around the player
and baking an area around an enemy means that the area has to be inside player's zone... And that's exactly what I was trying to avoid
oh, you're using the NavMeshBuilder
I'd suggest taking a look at the navmeshcomponents instead
using that package you can build navmesh at runtime from w/e geometry you want and have full control over the sources
I suspect you can also do the same on NavMeshBuilder, by not relying on unity for collecting the build sources and just not using bounds when building the navmesh. But, personally, I only have experience with the package I mentioned.
I'm using navmeshcomponents
That package is built on top of NavMeshBuilder afaik
I have no doubt about that, that's why I think you can achieve the same using NavMeshBuilder
he tried the package, but he's trying to procedurally generate terrain, and that makes it a bit trickier
I used it in the same scenario
in a procedural world?
it's just the Build method that takes localBounds is on the NavMeshBuilder, so I thought that was being used
yeah
i'm using it via script
same
this is a problem because it breaks the chunk logic
you are using the regular NavMeshBuilder
mmh. Right. But a chunk is still pretty big, it might lag a bit. I'm not sure if this can be a solution
Is there another..?
What happens if you call UpdateNavMeshData multiple times with different LocalBounds?
async private Task BuildNavMesh()
{
AsyncOperation ao = navMeshSurface.UpdateNavMesh(navMeshData, navMeshBuildSources);
while (!ao.isDone) await Task.Delay(meshUpdateTransitionPollFrequencyMs);
}
The terrain becomes smaller or bigger depending on the localBounds, if they're big enough, all the terrain is taken
in navmeshcomponents it's NavMeshSurface
I've got that
I'm using its setting
as you can see in the code
(there's the "navMeshSurface.GetBuildSetting()" method)
yeah, but you don't need NavMeshBuilder
I'm gonna go out on a limb and say NavMeshSurface probably calls NavMeshBuilder ;P
so.. I just need to call navmeshsurface.update[..]?
yeah, they probably end up calling the same cpp part of the engine
it has the BuildNavMesh method
but it takes no arguments
can't manually select sources
you can initialize it with empty navmeshdata, and then only update it
I'm doing just that
it creates "navmesh islands" around the points of interest
which slide all around the world
it just collects sources and then builds
yeah, I mentioned a few times that you don't really want to let unity to collect sources
in this use case
that's what I was doing
I know
@lament briar can you try calling UpdateNavMeshData (async or not) twice with different non-overlapping bounds?
sure
that's also what NavMeshSurface.UpdateNavMesh uses
depends on bounds size
you don't need bounds at all if you manage all the sources yourself
It drawed only the second
He does
20x20
okay now make sure both bounds are on top of the mesh.. I think it should create two islands, the way you want
they are
I think that the update clears the previus call
hmm
T.T
well that's still not been useless, collecting sources manually seems a fantastic way to reduce cpu load
so I'll use it
the problem is that he wants to create multiple partial navmeshes from geometry meshes that are larger than the navmesh bounds itself
I think you should just try generating navmeshes per chunk though
that's because if I create a very large navMeshBounds the terrain (And probably the objects in it) takes a lot of time to load
well if it's async, does that cause problems?
π€
can experiment with chunk size too
you're right, if the source gathering process is the only lag cause, then the terrain shouldn't lag
chunk resizing in my project is really, really complex ahah
would be good to profile that as well
i should rewrite half of the procedural code to adapt that
yeah, I'll now try on playmode with real chunks
it's a pain to debug in that scene because it takes about a minute to load all the world
and hotchanges doesn't work; they break some scriptableobjects logic in the inventory so I have to restart again ahah
I see, so the terrain chunks are much larger than a needed navmesh island
yeah, let me screen them
That's the world and a single chunk
That's the player in a chunk
as you can see, loading the whole world would simply be impossible for a medium-specs computer
even a single chunk is pretty big
if you guessed it - yes, it was really painful to profile all the world gen and make it as light as possible, and it still lags a bit; I'll have to profile again somewhere in the future
there's a NavMeshBuildSettings.preserveTilesOutsideBounds undocumented setting that I noticed when I was writing my navmesh factory, I made a memo to test out what it does exactly, but never actually did that
from its name it looks like it might preserve the navmesh between 2 updates with different bounds
maybe you should test it
ok, and how do I manually clear the old navmesh?
The flow should be something like an update for each bounds, and the a clear before updating again
so maybe a clear and 5 updates in a row, then again a clear and 5 updates in a row etc.
(that's an example)
if it actually works like its name suggests, you shouldn't clear the navmesh
but instead keep collecting the sources
and passing the in multiple updates with different bounds for each
in theory it should still delete old navmesh parts which lost their sources in most recent update
another solution would be to generate terrain navmesh up to mob persistence range, but only include obstacle sources in near vicinity of the mobs and the player
but it depends on how far mobs are still visible/active
I have absolutely no clue what's happening
but
the script that I created, only adding the terrain source (one per chunk), acutally.. doesn't lag
for the whole world
AND
it automatically carves the obstacles
without adding the sources
I'm really, really confused
..that's not totally true
it lags only when a chunk is generated
is that an actual Unity terrain ? or something custom
navmeshsurface collects the sources too, when you let it, so it's probably that
I'd try the solution with generating terrain's navmesh in a larger radius, and making it detailed only around areas of interest, it should be fast enough
If it's not that, is it possible the chunk is mesh combined by static batching?
is there a way to not do it?
i've tried with "collect objects" set to volume, all or children, all of them carve the obstacles
It takes 100ms for about two seconds reducing fps to 2
is there a way to do it async/carving manually in a "slower" way (with a queue that carves X objects per frame)?
baking the whole world is the best option right now, it's really game changing
I would remove 90% of the code that I did until now
and simplify a lot of things
I always update navmesh, it collects the sources when you call Build on the navmeshsurface
Oh, I see, I added my own update that expects a collection of build sources instead of collecting them automatically
and I collect the sources in an asynchronous manner
it depends on how you manage and store the game objects
Generally, it's a good idea to use any sort of space partitioning data structure to store the game objects so you can query them around the areas of interest. Separate build source chunking is a good approach too.
When areas of interest move, reassemble and merge only the parts that are active
that gets rid of unused build sources and updates the navmesh with new ones
and make the routine into a task, that only processes a limited amount of data per frame
so still on the main thread? how do you do that?
it was about the build source collection task
in my case it's just an async task that yields after a certain threshold
I can move a large part of that into a separate thread using the Job system, because for a lot of objects I use simple shapes instead of accurate models
but it performs fast as is, so it's a very low priority task for me
Hey,
I need to cast a method(bool) to a UnityAction<bool> or generically refer to that method in some other way
something like this:
{
if (idx == 0)
return new UnityAction<bool>(this.OnBoolChange);
else
return new UnityAction<bool>(this.OnOtherBoolChange);
}
So a unity event call can add a listener to this - I need to be able to refer to those methods (OnBoolChange and OnOtherBoolChange) generically but I have no idea what the syntax for that is in c#
oh, got it
That is the right syntax but that's the wrong function, doh
this is a textbook example of the xy problem
nah, I had the right method so it's more like the X problem
unless there's some deeper issue here - which I think I alluded to ('or generically refer to that method in some other way')
I should use basically all simple shapes
like cylinders or cubes, to carve out obstacles
or a combination of them
But how do I disable the auto-gathering and carving of obstacles?
the question is, why do you have a function that returns handlers
what are you trying to do
i am going to guess you are trying to
make a list of buttons for a UI, like an inventory
I'll try that later anyway, I'm leaving my house rn, but I'll try that tonight (about 8 hours from now in my location)
what method are you using to build the navmesh ?
I'm still using UpdateNavMeshDataAsync, for now
I'm writing a piece of code in a manager to link up a bunch of UnityEvent<> and their corresponding methods in other components. I had done all this by hand but because unity just loves to lose connections, I'm writing a bit of code to remake them when this happens.
okay but what is the UI
what is this
or what is it concretely
what is the game, and what did you encounter
I don't know how to carve my own objects
or how to do another function similar to this
because unity just loves to lose connections
this means you are in some pretty deep doodoo, because it doesn't make sense π¦
you are observing an issue, i'm not sure what the issue is yet, and i don't think you've identified the right problem
@undone coral I didn't think that detail was relevant to the specific question. What I've made is a colour picker.
okay, and you're saying you have a ColorPictureController that needs to wire up a dynamic tray of swatch buttons, and raises some kind of event for which color was picked
@undone coral Not quite, no.
that is weird then, maybe there's a call to navmeshSurface Build or Update somewhere in your code ?
those are the points that trigger the source collection normally
can you show me a screenshot of the color picker? i'll show you a code sample for how to do that UI
UpdateNavMeshDataAsync doesn't collect the sources on its own, it expects you to provide the collection
that's what I understood too from the chat that we had today
@undone coral I've already written it.. I've written this same thing dozens of times in numerous languages over the years, first time in unity. Basically the photoshop colour picker - you know, RGB, HSV, sliders so on. I fancied doing one of those more modern circle and triangle ones but decided to keep it simple. Anyway, I had a very specific question (how to refer to a method on a component generically) and I realised I knew the answer, I was just being daft and referring to a function with a different signature.
That's the navmeshmanager..?
okay it would make more sense to me, because in yavascript, doing
function getSwatchPickerHandlerForSwatchIndex(index) {
return () => swatchPicker.raiseEvent(index);
}
is like, a toxic thing to do even in javascript, but is something that i see
i am saying that based on the code snippet you shared, there is something very broken
and the words you used, "losing connections"
it's suggesting something is really messed up
about how you're doing things
part of this is that doing in yavascript
domElement.onvaluechanged = () => ...
is also, for all but the absolute most simple cases, flawed
@undone coral this particular bit of code is really just for auto-setup and I wouldn't need to do it if unity didn't keep breaking connections (I think this is more to do with moving files around in the project and unity complaining about that, losing references to things - that's the whole point of meta files though. I've been told I should only move files within unity and forget that better external tools for that exist)
navmeshsurface collects the sources on the main thread, no jobs or anything
hmm
you said "didn't keep breaking connections "
what do you mean?
losing references...
better external tools...
so it's up to you if you want to do this better*
but I'm not calling collectSources
@undone coral
this fellas
if I move my prefab, unity forgets that these connections exist
Maybe I know why..
which is deeply annoying
see, this is what i expected you had, and it's surprising it's a bool, and i'm trying to get to the bottom of what you are trying to do
I suspect NavMeshCarving is navmesh obstacles with carve enabled?
move the prefab and connections don't exist..
@undone coral so I'm annoyed enough to write a function to link them back up because it's tedious to do that
you might be editing the prefab in the scene, and not applying its overrides, or there's something flawed about how you expect prefabs to work and what is assignable* in there
don't use that
well like i said if you share a screenshot i can show some code that will be very illuminating
oh ok
That's going to be slower than just baking it correctly
carving cuts a hole in the navmesh at runtime after it has been generated
so how do I do that? I collect sources and then update it with the update?
how do I do that async? Threading shouldn't be used on gameobjects, iirc
NavMeshBuilder.UpdateNavMeshDataAsync is async?
Within a prefab, I would expect unity to be able to remember that it's referring to other objects within that prefab and let me move that prefab and associated files about in the project (along with their metafiles, so all the GUIDs should match up)
However, this doesn't happen - fine, it's a flaw in unity (I'd say that, rather than a flaw in my understanding - pointer fixup doesn't have to be this finicky) and now I'm writing some code to work around this wrinkle.
yes, but gathering gameobjects it's not
if you assign objects in that rollout that are inside the prefab, of course everything works fine
to build the sources
what do you mean move the prefab and associated files? what are you trying to do?
basically, looping between thousands of trees, reading their datas and creating a source
are you using source control?
that should be cpu intensive
there aren't any flaws in unity here... i am trying to help you understand what is going on
@rugged radish suggested doing x amount per frame in a task to make that async
ok
so handling this just like the whole world spawn
i guess before i make any more suggestions, coming from me, an experienced developer who knows way more about this than you do, do you at least agree you are probably making at least one big mistake, and maybe a bunch of small mistakes?
and if I, let's say, destroy a tree, I need to remove its source, and then update again?
yeah I would make that part of your world gen, it already knows everything that's needed for creating the navmesh, right?
hopefully
yeah, actually yes
wait but a tree is a perfect candidate for a navmesh obstacle carving
I'd just need to create another list somewhere, maybe ina navmesh manager created by me