#archived-code-advanced

1 messages Β· Page 30 of 1

undone coral
#

AWS NLB supports TLS termination with ACM certificates. you can download the certificate (it's inappropriate to call it a public key) and ship it with your game, in StreamingAssets or Resources as a text asset, then load it with SslStream

#

if you are using AWS

potent shoal
#

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
#

🫑

potent shoal
#

@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.

undone coral
#

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 πŸ™‚

potent shoal
#

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.

undone coral
#

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?

potent shoal
#

I do.

undone coral
#

i'm kidding but seriously there's a ton of stuff that already exists that smacks you with where the journey leads

undone coral
#

that looks nice

potent shoal
#

Thank you. I've been developing this game for the last 5 years.

severe topaz
potent shoal
#

Yes, I started this project with no game development knowledge.

undone coral
#

sick

potent shoal
#

it's essentially a bullet hell/boss battle type game, with pvp in the mix.

undone coral
#

there's a lot of potential for MMO Star Control II

#

emphasis on 2D, so that everything eventually gets shipped lol

severe topaz
#

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

undone coral
#

it looks great

severe topaz
potent shoal
#

This is an MMO, hence the master server.

severe topaz
#

oh boy, have fun with hackers and bots and lack of playerbase then

potent shoal
#

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

severe topaz
#

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

potent shoal
#

I think that depends on the developer.

#

These things are not so challenging to tackle.

#

With a little creativity it can be solved.

severe topaz
#

i'm not really sure if there are any exceptions to that, i've seen the same problem in every mmo/online game

undone coral
#

if you showed me a 3d space mmo i'd be worried

#

i mean capital Three D

#

i am relieved it's 2D

severe topaz
#

^

#

show me any 3d mmo at this point and i'd be worried

potent shoal
#

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.

severe topaz
#

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

potent shoal
#

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.

severe topaz
#

yeah but they still ended up making a game that found its' audience

potent shoal
#

That's true.

severe topaz
#

and i think that's way more important than everything else

potent shoal
#

That is also true.

serene grove
#

i have a photon issue guys

#

i ready to pay for helping to fix

shadow seal
#

Aside from that, ask an actual question in the chat

serene grove
#

i just need fix my issue

#

i so tired about it :/

shadow seal
serene grove
#

i trying but its not working :/

shadow seal
#

What?

serene grove
shadow seal
#

Right that isn't very helpful at all

serene grove
#

how can i get

#

rpctarget list

velvet rock
#

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

austere jewel
#

GameObjects are not components.

#

It shouldn't allow you to select it

velvet rock
#

Correction I can drag them in, but the editor selector only shows GO

#

Yeah the editor just sucks still, no new news I guess.

plush hare
#

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

misty glade
# plush hare 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)

plush hare
misty glade
#

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

plush hare
#

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

misty glade
#

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..?

plush hare
#

You mean like a guid string?

misty glade
#

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

plush hare
#

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

misty glade
#

Guids are basically Guids πŸ™‚

plush hare
#

If you send a GUID over a network, you send it as a string

misty glade
#

They can be fixed if you want them to be

regal olive
#

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

misty glade
#

Well, I mean, not necessarily - you said you were doing a custom implementation.. so why not encode it using something like ProtoBuf or MessagePack?

plush hare
#

Because C# would still need to work with a string

#

and it would cause allocations

misty glade
#

(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

plush hare
#

No collisions with my code πŸ™‚

misty glade
#

For things that are fundamentally some sort of ID where you need to know and sync and reference them - Guids are great

plush hare
#

I also wrote the serialization for my framework

#

and the compression

regal olive
plush hare
#

It wouldn't make sense to send a c# GUID over a network

misty glade
#

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. πŸ™‚

plush hare
#

Because it allocates garbage

#

you don't want to be sending tons of strings every tick

#

to communicate with an object

misty glade
#

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

plush hare
#

Ok so I've never used GUIDs before. So they're a 128 bit integer

#

regular integers are 32 bits

misty glade
#

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

plush hare
#

bandwidth increases exponentially per player joined

misty glade
#

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

plush hare
#

if you've got 300 players in a server, it matters

#

even then, I can compress my IDs to be less than 32 bits

misty glade
#

300 players sending 16 bytes 20 times per second is 100k/sec - and that seems pretty reasonable to me

plush hare
#

I'm high right now, so go ahead and give me a second to compute some things

misty glade
#

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.. πŸ™‚

#

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 πŸ™‚

pliant crest
#

optimize after

#

if anything

#

no point optimizing this if its only like 1% of the network overhead

brisk pasture
#

900 bytes is pretty small, if you were that worried about size you would not be using json in the first place

misty glade
# regal olive maybe it's better i ask here: i would like to make a buff/debuff system. lets sa...

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,
}
pliant crest
#

you really want to cache that value

misty glade
pliant crest
#

and not linq it everytime thou

misty glade
#

Yeah, but that's step2. πŸ™‚

#

FINE make me do more work... typing furiously

pliant crest
#

you don't have to write it

#

but more a fyi to the person who asked it

brisk pasture
#

if GetEffectValue needs to be cheap would just build and maintain a dictionary for it

misty glade
#
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?

#

πŸ™‚

pliant crest
#

not an interface /sad

misty glade
#

I'm gonna punch someone. πŸ˜‰

pliant crest
#

πŸ˜›

plush hare
#

@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.

brisk pasture
#

someone is undefined

pliant crest
#

why are you syncing every player

misty glade
#

Ok so .. hang on, you are thinking that you need to send location information to 300 players 30 times per second? ....

pliant crest
#

and not just within their local space

#

you can sync players that are local to them faster

plush hare
pliant crest
#

then the ones further away

plush hare
#

and that's not good practice

pliant crest
#

who cares at this point

#

thats a minor problem

plush hare
#

ok

pliant crest
#

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

plush hare
#

Would you personally use C# GUID values for tagging network IDs?

#

They aren't even collision proof

#

you have to do your own checking

misty glade
#

You said yourself you're only sending it once.. so... why do you care about optimizing it..?

plush hare
#

why not just iterate from 0

#

this isn't even an optimization

misty glade
#

They...... aren't even collision proof...?

#

oof, my friend

plush hare
#

What if you generate two GUIDs and they're the same value

pliant crest
#

what happens

#

if a gamma ray event hits

#

your memory

#

and swaps your id from 0 to 1

misty glade
#

heh

compact ingot
#

guid collision probability is one in 2ΒΉΒ²Β²

misty glade
#

what he's trying to say is that the chance of guids colliding is infintesimally close to 0

pliant crest
#

you are asking questions that basically dont' matter

plush hare
#

Iterating from 0 collision probaility: 0%

pliant crest
#

yeah

#

but why does it matter

compact ingot
plush hare
#

Ok

#

you're right

pliant crest
#

its capped at 300 thou

plush hare
#

you guys win I lose

#

GUIDs for everyone

pliant crest
#

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

plush hare
#

πŸ––

pliant crest
#

this is premature optimisation

plush hare
#

Ok

misty glade
#

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

pliant crest
#

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

plush hare
#

Yes that is generally how the industry does it

misty glade
#

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.

compact ingot
#

first step should be designing a game that can by synced realistically assuming normal-effort optimization and premade solutions

misty glade
#

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

compact ingot
#

hobbyist developers

pliant crest
misty glade
#

aye

pliant crest
#

slight inefficiency is better then dropped game project

brisk pasture
#

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

misty glade
#

this exact same conversation template occurs every week/day

brisk pasture
#

there is always more work to do in games, so decide what done enough is get it there and move on

compact ingot
#

you can use FindObjectByName and still sell 500k units

pliant crest
#

tbf i'll die on that hill

#

learn how to reference

#

😐

brisk pasture
#

i am agaisnt find object by name not for perf reasons though

#

it makes things fragile to change

compact ingot
misty glade
#

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 +

brisk pasture
#

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

misty glade
#

heh.. having a good game designer who .. you know, respects what's difficult and what isn't is amazing

pliant crest
#

depends on if the game designer understands the dev process

brisk pasture
#

then i worked with other ones that are just amazing, they work within the limtations

pliant crest
compact ingot
pliant crest
#

2000+ lines for a single method

brisk pasture
#

and are fine working out sacrfices with art and dev to make things easier for everyone

misty glade
#

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

compact ingot
pliant crest
brisk pasture
#

yeah had a project with a class that was 60kloc

compact ingot
#

its called C code

brisk pasture
#

scary part was it was C#

pliant crest
brisk pasture
#

ide just hated that one

compact ingot
#

i think method length is no differentiator of good/bad code

pliant crest
#

each modifier is added to create a skill

misty glade
#

i'm probably going to developer hell but i love singletons and static methods

brisk pasture
#

yeah buffs debuffs and stuff i have mostly done as 1 class per effect type thing that all implement a common interface

pliant crest
#

singletons are okay

#

statics outside of that i'm abit iffy about

misty glade
#

πŸ‘€

brisk pasture
#

if it works go for it

misty glade
#

works for me.. i just like the syntax of not having to FindObjectOfType<> or pass around references everywhere in my game

brisk pasture
#

have worked in a few singleton heavy proejcts and its fine. would be hard to add unit testing but otherwise fine

compact ingot
#

its totally fine if your project is well scoped

misty glade
#

I wanna send a network message? NetworkManager.SendMessage() I wanna play a sound effect? AudioManager.PlayOneShot(type)

brisk pasture
#

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

compact ingot
#

its not great for refactoring or working in teams

pliant crest
#

I wanna mine bitcoin? AdManager.MineBitCoin(); /s

brisk pasture
#

though i did end up making a basic depednecy injection system for unity i use at work now

misty glade
#

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

pliant crest
#

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

urban warren
brisk pasture
#

so i made one that suits needs of my workplace

misty glade
#

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

pliant crest
#

nice

compact ingot
#

i hope they never add a DI framework

pliant crest
#

DI has been around for about 4 years thou

#

atleast main stream ASP

#

might've been even earlier

urban warren
pliant crest
#

but thats when i started really working with it

#

wait nvm

#

covid

#

make that 7 years

misty glade
pliant crest
pliant crest
#

you can make the other stuff process it

misty glade
pliant crest
#

other stuff being the effects

#

and then just return the total damage

misty glade
#

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

pliant crest
#

fair enough

brisk pasture
# pliant crest might have to build my own...

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

misty glade
#

sometimes it changes targets, sometimes guys don't attack, sometimes they do "trample" damage (excess to the next target) etc etc etc

pliant crest
misty glade
#

it's... complicated. πŸ™‚

pliant crest
#

yeah fair enough

#

this sounds like a card game

misty glade
#

i'll show you a few sec of play, it's kinda neat actually

#

beta test this month

pliant crest
#

nice

urban warren
misty glade
velvet rock
#

Wait, does unity not serialize MonoBehavior that have the partial keywords?

misty glade
misty glade
pliant crest
brisk pasture
misty glade
undone coral
misty glade
#

(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

#

crew art is looking good .. battle game art needs a lot of work still but we'll get there

velvet rock
misty glade
#

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)

brisk pasture
#

yeah i turn my work machine off every night. get less weird things as a result of launching it fresh every day

velvet rock
undone coral
# misty glade

it's reassuring you are the kind of maniac that uses backticks in filenames

misty glade
undone coral
#

did you ever consider the sane and humble period

misty glade
#

i did, briefly, then had my morning coffee

undone coral
#

well roll me into your testflight

#

i'm ready chief

misty glade
#

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

undone coral
#

lol

#

listen you didn' tknow

misty glade
#
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

brisk pasture
misty glade
#

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

pliant crest
#

O.o

misty glade
#

jesus i have stuff in here that is honestly just magic

#

square rooting large numbers, for example

pliant crest
#

reminds me of the quake's fast inverse square root

regal olive
#

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

misty glade
misty glade
misty glade
#

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

pliant crest
#

its more a why is fps dropping so hard

pliant crest
#

that its lagging?

urban warren
misty glade
#

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

urban warren
#

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)

misty glade
#

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)

regal olive
misty glade
#

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

urban warren
misty glade
#

Yeah, I mean, that's what #3 is for

urban warren
#

Yeah, I was specifically referring to the saying

misty glade
#

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

urban warren
urban warren
velvet rock
#

If I put everything in one script it stops having these issues.

misty glade
#

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) πŸ™‚

pliant crest
#

-10 bugs +?? bugs

velvet rock
#

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.

misty glade
#

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

velvet rock
misty glade
#

and my quick test shows that it doesn't work at all for me

#

oops wait, I lied, i didn't save my file

pliant crest
#
for (var programmer in Team.Programmers)
{
  bugs += programmer.FixBug();
}

public class Programmer;
private int FixBug()
{
  return Random.Range(-100, 100);
}
velvet rock
#

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

misty glade
pliant crest
#

if they stopped doing so much magic behind the scenes

#

it would be easier to uplift

misty glade
#

eh, at the same time, I'm happy for a lot of the magic

pliant crest
#

but i dont know why they do so much magic i guess

misty glade
#

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

pliant crest
#

i'm still waiting on ECS to be released properly

misty glade
#

there's no chance in hell i would have been able to get this far if i didn't have unity

pliant crest
#

with 2D support

velvet rock
pliant crest
#

ikr

misty glade
#

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

velvet rock
misty glade
#

i'm sure you guys have seen that video floating around? "what i did in 2022" or whatever

austere jewel
pliant crest
#

tbf its also ms's fault

#

imagine creating .net standard

#

then throwing it away

velvet rock
# pliant crest imagine creating .net standard

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).

velvet rock
# pliant crest then throwing it away

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.

pliant crest
#

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

velvet rock
#

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.

potent shoal
#

@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.

tawny bear
tender light
tawny bear
#

Ah it's part of dots

mint valve
#

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

tawny bear
#

Use a [SerializedField] to reference it, in the code

mint valve
#

I want to do it in AssetPostprocessor

tawny bear
mint valve
#

I did, and after that I came here πŸ˜„

tawny bear
mint valve
# tawny bear 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

tawny bear
#

Store it in a separate variable?

mint valve
#

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"

tawny bear
#

ScriptableObject maybe?

#

Though given it's a class it might be passed by reference thus still destroyed

mint valve
#

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

tawny bear
#

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

mint valve
#

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

mint valve
#

yeah, I tried AssetDatabase.TryGetGUIDAndLocalFileIdentifier on that AnimationClip, it doesn't give you anything

tawny bear
#

Rip

#

I honestly have no idea

#

You'll just have to continue googling and hope you strike that gold on StackOverflow kek

mint valve
#

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 πŸ™‚

karmic viper
#

How would I specify a ToString

lament briar
#

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

lament briar
tiny ocean
#

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

undone coral
undone coral
undone coral
#

you can also read and write to these private fields

undone coral
mint valve
potent shoal
#

@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.

undone coral
#

and is it windowed?

#

and does each game server run many users? like dozens?

pale zinc
#

I can get the path to the containing

lament briar
#

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

undone coral
#

navmeshes are global and shared by all agents of the same size. what is your game?

hushed stirrup
#

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

hushed stirrup
#

It's a scripting issue. I have the animation set up properly, but the script is not triggering properly

sly grove
#

You said the code is running

#

if the code is running, then you're not doing the animation bit properly

hushed stirrup
#

But something is not being accessed properly. The animation is configured properly

#

It's just one bool that I am trying to flip

sly grove
#

well without any details it's not really possible to help

hushed stirrup
#

I have a box collider with a script "AnimationTrigger' that when the play enters the box collider it changes the animation.

sly grove
#

that's basically zero information.

#

share the code etc.

hushed stirrup
#

`public class AnimationTrigger : MonoBehaviour
{
public GameObject player;

void OnTriggerEnter(Collider other)
{
    player.GetComponent<Animator>().SetBool("isJump", false);
    Debug.Log("Change Animation");
}

}`

sly grove
#

great so - if this code is running, it's a problem with your animator state machine

#

or you just referenced the wrong player object

hushed stirrup
#

I am getting this error "Animator is not playing an AnimatorController " now

sly grove
#

that means you're manipulating a decativated or disabled Animator

hushed stirrup
#

... How is it deactivated? It's working until the player collides with the box collider

sly grove
#

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

hushed stirrup
#

Dude. I literally have no idea

sly grove
#

well start looking around

hushed stirrup
#

The player is in the scene

sly grove
fresh salmon
#

Yeah betting on "player variable refers to a prefab" too

sly grove
hushed stirrup
sly grove
sly grove
#

not the actual player

#

obviously it won't work

sly grove
hushed stirrup
#

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

sly grove
#

I already noted what your problem is

#

and how to fix it

#

you don't need to repeat this

hushed stirrup
#

You said I was trying to animate a prefab, but I'm not

fresh salmon
#

You are animating a prefab
Instantiating it when the game starts won't make all the other scripts reference the instance automatically!

hushed stirrup
#

I got it working. Thank you

shadow wraith
#

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?

shadow wraith
mortal gust
shadow wraith
# undone coral why?

im using one material for different meshes with different tiling and also texture files can be changed at runtime

undone coral
shadow wraith
#

minecraft

undone coral
#

hmm

light bane
#
 [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 🀷

sly grove
#

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

lament briar
#

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...

β–Ά Play video
#

Like that

lament briar
#

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

wild merlin
#

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?

lament briar
#

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

hybrid trout
lament briar
#

okay, thanks πŸ˜…

#

gonna check that there, hoped this channel would've given me more answers since it's more a code-related question

lyric dragon
#

Json format

rain stone
#

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

midnight venture
#

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

obsidian glade
midnight venture
#

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.

obsidian glade
midnight venture
#

True πŸ˜‚

pliant crest
raven spire
#

Does anyone know if there is an API for changing these 2 values? Can't seem to find it.

flint sage
#

They're generally EditorPrefs

#

Or in a config file in projectsettings

#

ProjectSettings/PackageManagerSettings.asset

undone coral
# raven spire

ugh look at those scopes. unitask, unirx, naughtyattributes, deform... this guy fucks

undone coral
#

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

pale zinc
#

that's no longer entirely true with navmeshcomponents

undone coral
#

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 😦

pale zinc
#

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

lament briar
#

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

split sierra
#

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?

gentle topaz
#

can you not just instantiate them in a rotated fashion instead of adding more variations to the list?

split sierra
#

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

gentle topaz
#

that's not how quaternions work

split sierra
#

I figured

gentle topaz
#

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

split sierra
#

thanks alot mate, I try to fix up the code (:

humble leaf
sly grove
dreamy turret
rugged radish
lament briar
#

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 πŸ˜›

rugged radish
pale zinc
#

it's a source that is used to build the navmesh from

#

can be a mesh, can be a collider

lament briar
#

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?

pale zinc
#

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

lament briar
#

what if I don't want to use neither?

pale zinc
#

since it needs to go into the 'build nav mesh' function, it's encapsulated as a NavMeshBuildSource

lament briar
#

mmh i guess I must do that at least for the terrain

#

right?

pale zinc
#

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?

lament briar
#

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

pale zinc
#

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

lament briar
#

😭 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

pale zinc
#

you just create one with new NavMeshBuildSource() and then

lament briar
#

but still, what is a source? How should I choose the transform, the size etc.

pale zinc
#

add the necessary data

lament briar
#

yeah man ahahah

#

I'm not getting what the necessary data is

#

that's my problem

#

for example

pale zinc
#

for terrain you need to set sourceObject according to that manual page

lament briar
#

should I do a loop around objects on my terrain and creare a source per object, sized as the object?

pale zinc
#

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

lament briar
#

if I use just the terrain as a source

#

right?

pale zinc
#

should be

lament briar
lament briar
pale zinc
#

yes

lament briar
#

mmmh... so the source is both the terrain AND the objects in it

pale zinc
#

that's why it's a list of sources

#

everything that should go into calculating the navmesh

lament briar
#

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..

pale zinc
#

making games is hard ^tm

lament briar
#

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

pale zinc
#

what's 'terrain' there?

lament briar
#

with a navmeshsurface

#

nothing more, for now

pale zinc
#

looks like it's the component?

#

should be the terrain data object

#

wait it's not a terrain?

lament briar
#

yeah it's not a plain terrain, not even in the game

#

it's a mesh

pale zinc
#

You're building your own navmesh from code, so you don't need a NavMeshSurface

lament briar
#

can't use unity terrains to do a procedural world

pale zinc
#

okay, so then the source shouldn't be a terrain

#

it's a mesh

lament briar
#

okay, already tried that, but i'm gonna try again

#

the sourceObject should be the mesh then?

#

the mesh component

pale zinc
#

you can also run CollectSources and check in your IDE what it returns

#

looks like it should be the Mesh itself

#

not the component

lament briar
#

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

pale zinc
#

use .sharedMesh instead of .mesh

lament briar
#

Did that, nothing happened

pale zinc
#

Although.. the manual does mention mesh.isReadable needs to be true

#

so make sure it is

lament briar
#

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

pale zinc
#

yeah that means isReadable is not true

#

it needs to be readable

lament briar
#

yeah

#

it's not giving the error right now

#

so the mesh is readable

pale zinc
#

the reason it became an instance is that when you access MeshFilter.mesh it creates a copy of the mesh

lament briar
#

it's also one of the default unity resource (the plane mesh) so it's readable by default

lament briar
#

not anymore an instance

#

but still, no navMesh shown

pale zinc
#

okay keep experimenting

lament briar
#

Thanks

#

btw, what are the area and component parameter? Should I use them?

pale zinc
#

areas are part of the navigation system; you can block areas for certain agents for instance

lament briar
#

"Describes the area type of the NavMesh surface for this object.". I'm guessing that's the.. agent type area?

pale zinc
lament briar
#

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)

pale zinc
#

that could work, but if it's a tall box it'll carve a hole in the navmesh at the bottom anyway

lament briar
#

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?

pale zinc
#

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

lament briar
#

oh right, forgot about that sorry

pale zinc
#

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

lament briar
#

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

pale zinc
#

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

lament briar
#

"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

rugged radish
#

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.

pale zinc
rugged radish
#

I have no doubt about that, that's why I think you can achieve the same using NavMeshBuilder

pale zinc
#

he tried the package, but he's trying to procedurally generate terrain, and that makes it a bit trickier

rugged radish
#

I used it in the same scenario

lament briar
rugged radish
#

it's just the Build method that takes localBounds is on the NavMeshBuilder, so I thought that was being used

rugged radish
rugged radish
#

same

lament briar
#

this is a problem because it breaks the chunk logic

rugged radish
#

you are using the regular NavMeshBuilder

pale zinc
#

shouldn't if you have one terrain mesh per chunk

#

is there a different builder?

lament briar
lament briar
pale zinc
#

What happens if you call UpdateNavMeshData multiple times with different LocalBounds?

rugged radish
#
async private Task BuildNavMesh()
{
    AsyncOperation ao = navMeshSurface.UpdateNavMesh(navMeshData, navMeshBuildSources);
    while (!ao.isDone) await Task.Delay(meshUpdateTransitionPollFrequencyMs);
}
lament briar
rugged radish
lament briar
#

I'm using its setting

#

as you can see in the code

#

(there's the "navMeshSurface.GetBuildSetting()" method)

rugged radish
#

yeah, but you don't need NavMeshBuilder

pale zinc
#

I'm gonna go out on a limb and say NavMeshSurface probably calls NavMeshBuilder ;P

lament briar
rugged radish
#

yeah, they probably end up calling the same cpp part of the engine

lament briar
#

it has the BuildNavMesh method

#

but it takes no arguments

#

can't manually select sources

rugged radish
#

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

pale zinc
rugged radish
#

which slide all around the world

pale zinc
#

it just collects sources and then builds

rugged radish
#

yeah, I mentioned a few times that you don't really want to let unity to collect sources

#

in this use case

lament briar
pale zinc
#

that's what NavMeshSurface does though

#

this is the code from NavMeshSurface

rugged radish
#

I know

pale zinc
#

okay

#

Then I'm not sure what you mean x3

rugged radish
#

that's why I use .UpdateNavMesh

#

which takes any collection

pale zinc
#

@lament briar can you try calling UpdateNavMeshData (async or not) twice with different non-overlapping bounds?

lament briar
#

sure

pale zinc
#

that's also what NavMeshSurface.UpdateNavMesh uses

lament briar
#

is that ok?

pale zinc
#

depends on bounds size

rugged radish
#

you don't need bounds at all if you manage all the sources yourself

lament briar
#

It drawed only the second

pale zinc
#

He does

lament briar
pale zinc
#

okay now make sure both bounds are on top of the mesh.. I think it should create two islands, the way you want

lament briar
#

And that's without the second update

lament briar
#

I think that the update clears the previus call

pale zinc
#

hmm

lament briar
#

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

pale zinc
#

I think you should just try generating navmeshes per chunk though

lament briar
pale zinc
#

well if it's async, does that cause problems?

lament briar
#

πŸ€”

pale zinc
#

can experiment with chunk size too

lament briar
#

you're right, if the source gathering process is the only lag cause, then the terrain shouldn't lag

lament briar
pale zinc
#

would be good to profile that as well

lament briar
#

i should rewrite half of the procedural code to adapt that

lament briar
#

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

rugged radish
lament briar
#

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

rugged radish
#

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

lament briar
#

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)

rugged radish
#

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

lament briar
#

mmh.

#

ok

#

I'm gonna try that

rugged radish
#

in theory it should still delete old navmesh parts which lost their sources in most recent update

lament briar
#

didnt'work

#

setting it to true spawns no navmesh

rugged radish
#

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

lament briar
#

ok

#

so

rugged radish
#

but it depends on how far mobs are still visible/active

lament briar
#

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

rugged radish
#

is that an actual Unity terrain ? or something custom

lament briar
#

Custom, custom

#

it's a mesh

#

(unity terrain was not enough personalizable)

rugged radish
#

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

pale zinc
#

If it's not that, is it possible the chunk is mesh combined by static batching?

lament briar
#

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

rugged radish
lament briar
#

wait

#

so the update does the same thing but it doesn't lag?

rugged radish
#

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

lament briar
#

mmh

#

any tip on how to build mine?

rugged radish
#

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

pale zinc
rugged radish
#

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

knotty sage
#

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

undone coral
knotty sage
#

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')

lament briar
#

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?

undone coral
#

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

lament briar
#

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)

rugged radish
lament briar
#

I'm still using UpdateNavMeshDataAsync, for now

knotty sage
#

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.

undone coral
#

what is this

#

or what is it concretely

#

what is the game, and what did you encounter

lament briar
#

or how to do another function similar to this

undone coral
#

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

knotty sage
#

@undone coral I didn't think that detail was relevant to the specific question. What I've made is a colour picker.

undone coral
knotty sage
#

@undone coral Not quite, no.

rugged radish
undone coral
#

can you show me a screenshot of the color picker? i'll show you a code sample for how to do that UI

rugged radish
#

UpdateNavMeshDataAsync doesn't collect the sources on its own, it expects you to provide the collection

lament briar
#

that's what I understood too from the chat that we had today

knotty sage
#

@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.

undone coral
#

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

knotty sage
#

@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)

rugged radish
# lament briar

navmeshsurface collects the sources on the main thread, no jobs or anything

undone coral
#

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*

lament briar
knotty sage
#

@undone coral

#

this fellas

#

if I move my prefab, unity forgets that these connections exist

lament briar
#

Maybe I know why..

knotty sage
#

which is deeply annoying

undone coral
#

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

pale zinc
# lament briar

I suspect NavMeshCarving is navmesh obstacles with carve enabled?

undone coral
knotty sage
#

@undone coral so I'm annoyed enough to write a function to link them back up because it's tedious to do that

undone coral
#

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

pale zinc
#

don't use that

undone coral
#

well like i said if you share a screenshot i can show some code that will be very illuminating

lament briar
pale zinc
#

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

lament briar
#

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

pale zinc
#

NavMeshBuilder.UpdateNavMeshDataAsync is async?

knotty sage
# undone coral move the prefab and connections don't exist..

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.

lament briar
undone coral
lament briar
#

to build the sources

undone coral
#

what do you mean move the prefab and associated files? what are you trying to do?

lament briar
#

basically, looping between thousands of trees, reading their datas and creating a source

undone coral
#

are you using source control?

lament briar
#

that should be cpu intensive

undone coral
#

there aren't any flaws in unity here... i am trying to help you understand what is going on

pale zinc
#

@rugged radish suggested doing x amount per frame in a task to make that async

lament briar
#

so handling this just like the whole world spawn

undone coral
lament briar
#

and if I, let's say, destroy a tree, I need to remove its source, and then update again?

pale zinc
#

yeah I would make that part of your world gen, it already knows everything that's needed for creating the navmesh, right?

lament briar
#

and since it's async it will not lag

#

right?

pale zinc
#

hopefully

undone coral
lament briar
#

I'd just need to create another list somewhere, maybe ina navmesh manager created by me