#archived-code-advanced
1 messages ยท Page 72 of 1
the thing being passed in is treated as a readonly object, it isn't being updated by the other classes
Its still a parent being passed to a child, which is usually a sign something is upside down
theres probably a way easier way to do what you want, and usually in some way or another it means inverting your logic upside down from what you have atm
for example, the healthbar sits as a child of the canvas, and updates its display whenever the tank that caused its instantiation's health changes
Can you show an example of the code that causes this to happen
like here is an example of the healthbar script
That is indeed exactly as I said, that 100% is a child mutating the parent
it just looks like subscribing to an event... but that counts as a mutation
and thats a big code smell
i guess, but its decoupling the rendering of the healthbar from the the tank in this case
Nah you are now tightly coupled to specifically being a health bar for a MiniTank and you cant be a healthbar for anything else
i dont follow
You cant pass in something other than a MiniTank or derivation of that to Init(...)
owner cant be anything but a MiniTank
Youve tightly coupled yourself to the parent
yeah, thats true, but i could convert that to a generic type if i wanted to, but in my case its not needed
Or... you could not tightly couple to the parent at all
Why doesnt MiniTank handle mutating the health bar instead, Parent -> Child
Specifically, show me the code where you invoke OnTookDamage
this is in the mini tank class
sadly not
What I am expecting to see is
OnTookDamage?.Invoke(this, New FooEventArgs(...));
Or whatever
Where do you have the actual event being invoked
There we are...
Why not just have the code that modifies the health bar right there
because the healthbar isn't guarenteed to be attached to the tank?
Thats fine
Whats the issue? If it has a healthbar, modify it, if not, no problem
also its NOT a component of the tank or a child for that matter
so its a pain to "find"
Thats fine
since it exists on a totally seperate game object who's lifecycle differs from the tank
You should have some kind of core "service" that knows where the health bars are in some way
But it looks to me like all your woes are stemming from this heavy coupling of Child->Parent you have done, and having children mutating their parents which is a very fast route to spaghetti town
i guess i just don't see why i would want to have to find the reference to the healthbar each time i want to modify it since caching it on the tank is pretty simmilar to just subscribing to an event the tank emits ๐ค
I personally wouldnt even do that
In terms of if you have to find it each time, that depends on if we are talking about numerous healthbars or 1 that is always the same
But overall I prefer storing all this data that matters not on my monobehaviors, cause you run into all these sorts of weird issues where you have to figure out "who" or "what" is your "source of truth"
currently the intention was that the health bars will return to a pool when they are not in use (tank is offscreen), then they are pulled from the pool whenever they are needed again, and that can mean they are assigned to different tanks each time
I prefer storing all my "matters" data in a single source of truth that everything else mutates and listens for changes on
this way if you have like 200 tanks, but only ever happen to see like 20-30 of them, you wont have 200 healthbars in memory
I would have a service that handles tracking which health bar is assigned to which tank then, that doesnt exist "on" anything
I dont think a healthbar MB should care who its assigned to, and it should literally just have simple mutation methods on it, like:
SetMaxHealth(int maxHealth) { ... }
SetHealth(int health) { ... }
SetVisible(bool visible) { ... }
And then exposing the Transform prolly so you can modify that
And then the service tracks the relationships of Tanks <-> Healthbars, and you can do stuff like:
HealthBar HealthBarFor(Guid tankId) { ... }
HealthBar AssignHealthBarTo(Guid tankId) { ... }
void UnassignHealthBarFrom(Guid tankId) { ... }
void RedrawHealthBars() { ... }
etc etc
Tanks shouldnt care about their health bars, health bars should care about their tank, the service operates "overhead" controlling that stuff, etc etc
you'd still need to be able to force the update on the health bar whenever something on the tank changed that the healthbar needs to relay to the user
Absolutely, the TankService would handle that
So chances are TankService injects HealthBarService, and Tankservice can call methods to update the values of Tanks health and tell the healthbar service to redraw at the end if anyone has changed that matters
would it still make sense to decouple the various services to the components they relate to, like a healthbar service for healthbars, etc ๐ค
Nah its fine for HealthBarService to be tightly coupled to the Healthbars, since that is its "job" so that makes sense
This is my example pic of the stack I use that keeps everything super organized. I have been falling in love with this the more I use it, everything feels so smooth to implement
hm ill have to give that a shot, always open to try new things ๐
I got a blog post here detailing how I set it up including downloads for my classes needed to implement it
https://blog.technically.fun/post/unity/building-a-gamestate-with-zenject-in-unity/
and a link to my git repo showing the example project
cool, ill check it out tomorrow, getting late here
so there is no way I can do this without converting the method to a task?
rip, I'll just make two seperate methods
Hi
I have a state machine for my enemy ai, it goes like this, Find Cover -> Take Cover -> Shoot Player -> Take Cover (repeat)
but i want to make a slight modification to it (for another enemy type)
so it becomes
Find Cover -> Take Cover -> Rush Player
with my current architecture, I would need to duplicate a lot of code in order to make this work
how can I design my state machine so it is more open to modifications
are your states not abstracted?
they are
can you show a sample of how you construct the fsm
sure
this is what all states derive from
public abstract class EnemyBaseState
{
public abstract void EnterState(EnemyStateManager enemy);
public abstract void UpdateState(EnemyStateManager enemy);
public abstract void ExitState(EnemyStateManager enemy);
}
for example here is the find cover state
public class EnemyStateFindCover : EnemyBaseState
{
public override void EnterState(EnemyStateManager enemy)
{
int ind = Random.Range(0, enemy.CoverPointsSet.items.Count);
Vector3 point = enemy.CoverPointsSet.items[ind].transform.position;
enemy.AgentMoveTo(point, 0.5f, delegate
{
enemy.SwitchState(enemy.StateTakeCover);
});
enemy.CoverPointsSet.Remove ( enemy.CoverPointsSet.items[ind] );
}
public override void UpdateState(EnemyStateManager enemy)
{
}
public override void ExitState(EnemyStateManager enemy)
{
}
}
the problem isnt with creating new states or logic
its with changing the structure of the state machine
show a sample of where you construct the fsm
like if i wanted to create a new enemy type that just rushed the player
here is a snippet from state manager
private void Start()
{
_currentState = StateFindCover;
_currentState.EnterState(this);
DisableRagdoll();
}
private void Update()
{
if (!_isAlive) return;
_currentState.UpdateState(this);
}
public void SwitchState(EnemyBaseState state)
{
_currentState.ExitState(this);
_currentState = state;
state.EnterState(this);
}
so construction is not abstracted
consider the following
class FSM {} ^ what you have above but state agnostic
class EnemyType1
{
void Start()
{
this.fsm = new FSM();
fsm.AddState( new StateFindCover());
...
fsm.SetState(fsm.States[0]);
}
}
for example
check this as example of similar code base construction https://github.com/ashblue/fluid-behavior-tree
oh i see
but what about the state transitions
for example in my state FindCover
after finding cover it transitions to TakeCover
so these states are tied together
but lets say, after finding cover i want it to rush the player
two options, you either allow states to switch states
or you abstract the transition itself
first is simpler all you need is to have access to the root fsm in your state base class
second is the "proper" way that makes an fsm and fsm
yeah abstracting transitions is what i have been thinking about
but i just have no idea how to implement it
class Transition
{
public Transition(State from, State to, Predicate condition)
}
i guess these transitions i would need to store in the state manager, as opposed to states themselves?
or
class State
{
List<Transition> _transitions;
}
void Start()
{
fsm.AddState(new StateFindCover()).AddTransition( .. );
}
reason about fsm as an object, no "state managers" just the fsm
okay
you shove stuff in, it does things, its a machine
any Unity UI layout technique to achieve this sort of layout?
Unity's default Grid Layout sucks
you can add the Layout Components to the gameObject
The component name is GridLayout
that's not what I described above
oh I just noticed sry.
no probs mate โฃ๏ธ
๐
can you help me?
Im having a problem with my NetworkRigidbody.
Im using Unity Version 2022.3.5f1 and Netcode for Gameobjects 1.4.4 . I have one Player prefab with my Movement Script and a Network Rigidbody. On the host side everything works and the Rigidbodys are isKinematic = false but on the Client side its isKinematic = true. I dont know why. I tried to set the IsKinematic in the Await or the OnNetworkSpawn but both didnt work.
Do the children all have the same sizes?
If so it's trivial to write one yourself, otherwise yeah it's going to be iffy.
ideally not, but for simplicity, yes
for now I'm doing a fast layout system that literally asks us where to put children for every child count between 2 specifiec supported amount
saves as data
but has a button that makes gameobjects for editing, and then another button that reads those game objects into these dats
(light mode warning btw)
Should be pretty trivial to calculate where the children should be, given all the necessary information (container size, child size, gap)
oh wait, you mean it's pretty easy?
This is a weird one to choose the channel for as it is about animation but the problem I'm having is related to script.
PROBLEM
after switching the player model animator only works after manually interacting with it or saving and then compiling a script.
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
Yeah.
if it were just math, I'd do it. but Unity's UI Layout system has it's own public and internal APIs you have to follow if you want all the other layout components to work effectively
๐ค
I mean that you are doing the grid layout yourself and not using any UGUI stuffs, so those shouldn't matter to you?
There's nothing stopping you from manually setting where each child should be, and not using any layout components at all.
true that. this is a quick solution though; just to get things working. a dynamic grid would be really better. you know, it's one of those things you'll save in a gist to use it later too
Question: I'm planning on implementing a driving system into my game, and I actually want my player to open their car door and climb inside when interacting with the vehicle. I can easily set up animations and scripts for the vehicle, but my question is how would I go about the implementation of the mapping of the player's hand to the car door to open it, as well as mapping the player to properly sit inside the vehicle?
I suggest that you simply lerp the player to the position of the start of the animation then play the animation. Do not lose too much time in details.
Haha, yes it does! There's alternative grid layouts out there but in the meantime you'd just stick with vert/horizontal or a combination of both
^
or just write your own script to add the margins in per row/element
In Profiler, i have a lot of time spent in "Other" category, but nothing in hierarchy says exactly where. It just lives in the "Self MS" category of PlayerLoop (top line in hierarchy)
Does this mean some random script is probaby slowing it down?
I have no animation, AI, particles, neworking, loading. I have like 5 audio sources but that's only utilizing .5% of audio CPU
This is most likely the editor
It's in a build
Show a screen shot
You have FPS limit
I know
Let me show you a "normal" frame for comparison
See, nothing in "Self MS"
on PlayerLoop line
And what is the issue ?
have you tried to turn of all gameObect and profile a empty scene?
Because, in either scenario you are hitting your target frame rate
Not yet
It's just a matter of understanding how Profiler works and what these mysterious spikes mean. Because "PlayerLoop Self MS" is extremely vague
Then I have no idea. Self MS means that it is doing something that is not tracked by something in "Child" profiler maker.
Yeah. I noticed the spike is in the "Other" category, so I googled that and it said this
Which isn't really too helpful tbh
My point is, what are you investigating ?
I understand that you want to know what is being done in profiler loop. However, I doubt it really matters.
I can help you with trying to find performance gain, but I do not know any things about the self ms of the playerloop
Also, you might be interested in: https://docs.unity3d.com/ScriptReference/LowLevel.PlayerLoop.html
That's ok, there doens't seem to be much info on this Self MS in PlayerLoop thing. That's why I'm asking around.
It just concerned me that in a Scene with only my scripts running, I'm getting these random 3ms delays the profiler doens't seem to help me interperet, which I thought was largely the point of profiler
No idea how it can be relevant
What do you mean 3ms delays ?
You are hitting your target frame rate
That is a test scene with 0 graphics. But if I'm targeting 72fps or higher down the road (it's VR), random unexplained 3ms spikes can start becoming a headache?
I would start by having a scene that represent the target loads you want.
Then, investigate.
Also, did you try the deep profile option ?
It might be able to discover more.
Yeah I do have deep profile on
And, did you look at the timeline. Sometimes there is other things happening in the job system
And, at the end of the day, the profiler is not the perfect tool.
You better use native tooling
If you want the best accurante information
Yeah here is timeline on a slow frame. But I don't really know how to interpet it
Is there a recommended one for Windows?
No idea.
Hi everyone I really need some help, how can I go about doing a melee combo system with the input system? I've tried many methods and none of them seemed to work for me
Your combo system should be agnostic of the input system you are using.
You need to add a layer on top of it. Such as tracking what was the latest attack done, what attack can be done next.
@zenith panther exactly what @dusty wigeon said* . The inpiut system is responsible only for telling what is the player inputing to your game
A combo system need to be separated & custom to your own needs , if you need pointers give us more context on what exactly you are trying to do ๐
I understand! So I want to make a simple combo system for a hack and slash game as I'm doing a challenge with a friend, the combat I was taking reference to devil may cry with its melee combat, thats kinda where I'm going for it
So I want it to go like idle hit 1 > hit 2 > hit 3 > idle, something like that but I've just not been able to do it yet
What are your experience in scripting ?
I'd say I'm intermediate, I'm not an expert in it but I know common knowledge for it
So, you familiar with concept such as polymorphism ?
How well do you understand ScriptableObject ?
I'm not familiar with polymorphism, as for scriptable objects, I know a little bit of it
I would have asked this question in code general but it sometimes gets missed which is why I went here
Then, you should learn more about polymorphism as it is one of the most important concept of coding in Object Oriented Programming. It is also a most for what you want to do.
ScriptableObject is also something that would be really useful as it would enable you to create "Definition" of what a combo is. By example, you could define, that this particular weapon holds 3 attacks that each diverges in others.
There is other ways, however, I believe this is the best way to achieve a modular and complet "combo system".
Finaly, you can also just follow a tutorial which would probably more attune to your level of expertise.
(There is hundreds of tutorial)
Thank you! I'm still quite far until I'm able to do programming without asking for help ๐
@zenith panther the most important thing you need to learn is how to have the state & the good data so you can apply the logic that you want ๐
In your situation you can start by doing a simple proof of concept that have a list of event you recieve from your input system.
And use it as a "Pile" when the first one is done , you remove it from the pile & play the next one.
Then you add conditions : Like A can't combo after D but can after B & E , etc ...
one by one for example. it's def not the best way to do it because it will be hard to scale but that should get you started to try different stuff to get to the point you want to go.
Thank you! All of this is helpful stuff for me to learn, I do appreciate it ๐
So, I've been refactoring a bunch of code lately, looking for better ways to access scripts with limited dependencies. For example, your player has an inventory and an equipment object class. The inventory keeps track of the player character's general storage and the functionality of picking up and dropping items, while the equipment class contains info for what items are currently equipped to the character. Now, my problem is trying to understand the best way to cross reference these classes for when I want to take an item from my inventory, and equip it to my equipment class.
Early on, I felt like I shouldn't really expose the whole class to each other since I only needed to access a little amount of functionality between the two, so I thought about just subscribing to events to access those methods. However, as the project grew, so did the amount of events I needed and it quickly became more extra code to write than I wanted.
Next idea was to forgo the subscriptions and just expose the whole references to each other. For the most part, this works pretty well as long as I just don't touch stuff I'm not supposed to. It just seems like focusing too much on accessibility created more work and problems than I needed, especially considering that we can't assign data into a mono's constructor. By its nature, we're heavily encouraged to use a dependency injection approach, and with that alone makes it hard to limit what data can be accessed.
With that in mind, I feel like perhaps it's better to go heavier with a service locator approach, such that all objects that my player references, too shall have a reference to the service locator layer (the player in this case). This would mean that classes like inventory and equipment will still be referenced by the player, but for them to access each other, they will instead reference the locator and go down the reference tree. This could be done by a static (singleton) reference, or by sending a parent ref into each class.
service locator approach
wuh oh
Most of the time thats an anti-pattern and has better ways to do it :x
great approach when done properly
A lot of the networking libraries use a similar approach is to why I've got this idea in mind. ;)
This pretty much digs into why I set my stuff up in my project the way I did, by separate my GameState out into its own "layer" that doesnt exist on MonoBehaviors, and instead is an INotifyPropertyChanged tree
I then just bind my services to subscribe to changes to specific areas of the GameState tree, which is very easy to bootstrap after the boilerplate code is complete
I have a pic here somewhere, one sec
I wont say its the best way, but boy does it feel smooth and easy to implement everything once the boilerplate is complete
Ah, that does seem pretty interesting. I think someone else was trying to sell me on a similar approach.
Hi, could someone explain to me how to build Steam's GameNetworkingSockets for Android?
I've been trying to do it for days and it's being extremely difficult โน๏ธ
What is the nature of the dependencies between the equipment, inventory and player system ?
Does it boils down to:
Player owns an inventory ?
An equipment is located in inventory ?
An inventory item is equipped ?
Player owns an inventory, equipment is independent of the inventory but uses inventory to equip what is available to the player. Most of these classes are divided by a slot type and its requirements, as only certain items can be stored in those specific slots.
Inventory Slot, Equipment Slot, Ability Slot, Hotbar Slot
This is more an example anyway as I've other issues with controller needing events to the equipment class to equip the item when selected.
So again, more cross references despite the player owning all of these objects
Would that represent correctly the situation ?
Yeah, not too sure about the slots there however.
I thought you said equipment has equipment slots
Right, inventory would have slots too in this case ;)
I've a general base type slot which each of these systems inherit
Alright, so the issue is the relation between inventory, equipment and player ?
some covariance garbo to make hotbar work with types
Yeah, correct.
Hello if I have a bunch of planes which are my floor tiles and I want to create one big mesh collider the shape of all of them together how would I approach this? is there a way to group all these mesh renderers and gameobjects together to create the mesh collider?
or is there some asset that already does this?
I see no particular issue in the relation they have.
What you do not like ?
Because it is pretty straighforward
Equipment does not know anything about the player.
Inventory does not know anything about the player as well.
Inventory does not know directly about the equipment as well.
I guess my complaint is just in an expanding project, I'm feeling like I am cross referencing too much, and it's obviously because of implementation of stuff I did not have planned at the start.
This is a common complaint I have with the way Unity out the gate recommends storing all your game state on individual MonoBehaviors on your game objects, which seems easy at first but yeah, it basically is a road that leads you straight to this issue you are now experiencing.
As like I mentioned, my controller class needs a reference to the equipment, so now I've a reference over to that from that class. I've lesser scripts which need some relevance in these systems to keep them happy.
My general rule of thumb I follow is: if its not something that conceptually exists "in" the world, like it doesnt have a scale/rotation/position or a sprite... I dont put it on my Monobehaviors
Sure, what the issue is there ? Does the equipment knows about the controller as well ?
Everything you just describe to me is the ideal scenerio
Yeah, honestly from just that it seems fine, but I do have smaller scripts like modifications to the character which needs to be cross referenced to the abilities, equipment, stats. Just like, these lesser but more numerous features I'm implementing.
Maybe those are the issue.
Elaborate on it.
If you open an ability what are its reference at the moment ?
Perhaps, but I've actually building this large trigger system for character events, trigger when hit, trigger when attacked, trigger on cast, cast on interval
this applies to the neutral state of the character, as well as abilities that can cast
global modifiers you can think of
So, the abilities controls the character ?
abilities and items do need to know about it, especially when you equip something
well, let's say you have a trigger on hit -> cast fireball, but you dont just want to cast a level 1 basic fireball, you want it to be modified by gear and other modifiers
Oh, so an abilities is affected by modifies which can be in an equipment or directly on the player ?
I still do not see an issue.
so there's this large subscription system I got which helps keep mods updated, and caches when equipped.
Yeah, that's what it's looking like
There is no issue there
It is still the ideal scenario
Extract what is the source of the reference to something else.
Equipment has a reference to the player because the player has modificator.
Extract the concept of modificator
So, for the controller that you need access to give input to these classes, where would you stick that
Abilities, equipping
Why does equipping needs input ?
The UI will manipulate an equipment
But never the equipment will listen to input
Am I wrong ?
True, just if you've a statemachine with abilities and such too, you can't just give input to move if you're casting
so there must be some communication with those
Alright, so the abilities control the player ?
abilities limit the actions of player I guess
The abilities says do X, do Y to the player ?
Then what is the issue ?
The player knows what abilities is being played
Abilities does not need to know anything about input
If the player "plays" the abilities
You might want to have the abilities control the player, that it is possible.
Then, at this moment, you have the first situation where you need to think a bit more.
Because now, you have a player that has abilities, and abilities that have the capacity to control the player
Is it our situation ?
They do limit the player, yes. I think I can move some logic out of it though. It's something I been meaning to refactor for some time now.. hmm
If they limit the player, they do not control the player.
And we are still in an ideal situation.
As they do not need to know anything about the player
Basically what you have there is what I am doing, so I guess the problem is more with my smaller scripts, or rather subscription systems.
Are we primarily talking about an issue of Maintainability here? Like its becoming difficult to maintain and keep things organized?
Well, back to the modhandler. Abilities, equipment, player statistics rely on modification objects, which you can think of as gear affixes and even more sillier ones like trigger fireball when hit.
Yeah, pretty much
Mood. Pretty much what I have brought up above was my solution. Im sure others exist but if you want I can hook you up with my guide I wrote on how to implement my approach if you like
The events keep a lot of the stats and trigger effects updated, so when they are equipped, or learnt, they must contact each other and assure that they are updated accordingly with the newest mod.
I also very quickly grew tired of all my monobehaviors becoming just a tangled mess of "everything referencing everything else" and a billion events all over the place, and it just felt like a spiderweb of things connected to other things
So any time an item is equipped, or an ability is learnt, I've got to pass this reference around for them to subscribe to. And, similarly, invoke a recalculations betweem the mods.
Your issue is that you have everyone listening to everything.
Use a central system such as a modificator.
The modificator listen to what it needs to. The abilities add or remove a modification.
Yeah, it could use some adjustments, but I think the idea is there for that I need to cache as much as possible because with what I have it's too much to calculate per hit
~~```
ArgumentException: The number of vertices in the combined mesh (66792) exceeds the maximum supported vertex count (65535) of the UInt16 index format. Consider using the UInt32 IndexFormat for the combined mesh to increase the max vertex count.
this is what I get when I use the CombineMesh() am I doing something wrong?
```csharp
MeshFilter[] meshFilters = floor.GetComponentsInChildren<MeshFilter>();
CombineInstance[] combine = new CombineInstance[meshFilters.Length];
for (int i = 0; i < meshFilters.Length; i++)
{
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
meshFilters[i].gameObject.SetActive(false);
}
Mesh mesh = new Mesh();
mesh.CombineMeshes(combine);
transform.GetComponent<MeshFilter>().sharedMesh = mesh;
Here's the code~~
also a question i've been looking for, assuming I do cache all this stuff, how do I approach a problem that I remove some modification from an ability when it's on the scene. If I have it all cached, and I delete that reference, it'll create a bunch of errors.
Usually, when doing it calculation, you have something (Really simple) such as:
-> Enemies hit Player
-> Enemies modifies hit
-> Player take hit
-> Player modifies hit
The modifies part is what you struggle with I guess
Well, let's say you have 20 mods of +% fire damage, some flat damage modifiers to fire, then you've also got modifiers for the ability composition such as speed and range
recalculating this off a rapid ability, from the player and allies, would add up quite a bit
So, you have performance issue ?
yeah, it's actually quite a project with what elements ive been going with
Did you profile ?
Did you profiles.
Yeah, without caching it creates quite a mess
yeah thats pretty normal to do for a game like that
So, what you want is caching as you said.
caching those stats and only modifying them when they have changed is pretty reasonable
It has nothing to do with events.
Well the event is when the stats need to be re-cache
It does needs to be tentacular.
and as Mao said, there's a buncha different types of triggers that can cause the stats to require an update
Yeah, it's quite a nest of operations and ability subsystems
if you have a spell that triggers a spell, then you need to now modify both lol
@regal lava Ill just say this is an example of what my system excels at, since I even recently added a sort of mechanism to open a transaction and then commit it on my game state, so if I modify like 5 stats at once it wont retrigger the recalculation/redrawing 5 times, but once instead after I have finished making changes
You can do all of that in a subsystem like a modificator
I cant actually find info how diablo-likes do it though, and when it comes to unequipping weapons with modifiers that affect abilities, I assume it snapshots the cache somehow to prevent you discarding that weapon and nulling refs
What do you mean ?
I can do something like
using var txn = GameState.OpenTransaction();
GameState.Player.Stats.Strength = newStrength;
GameState.Player.Stats.Intelligence = newIntelligence;
GameState.Player.Stats.MoveSpeed = newMoveSpeed;
txn.Commit();
And it will then trigger all the distinct events that have been queued up, and wont re-trigger the same event twice, which is quite handy
You dont put this kind of logic on the items themselves. All this logic should exist in a seperate layer that cant be destroyed or whatever, and is a "service" or "business" layer that handles tracking things.
Even on another layer, when would I know to discard it then if the weapon is destroyed
What do you mean ? If the weapon is destroyed it removes the modification it added
Why would the weapon be destroyed, as an example
It is that simple.
Also, big project are usually a mess. They do what they with what they have and it is usually ugly as duck
The standard are most of the time low.
Truer words have never been spoken XD
Hmm, yeah let me think about the logic a bit more then. Perhaps I'm binding stuff too much, but right it shouldn't (but it does ^^ )throw errors regardless if I discard a weapon with a mod. Rather, it should just not apply the trigger anymore
You try really hard to keep it not a mess, but somehow even with the best intentions and all the effort in the world, you still end up with at least some hacky spaghetti in there
But with a really good set of folks doing code reviews, you can at least keep your spaghetti index down to a reasonable level and under control
can confirm, i live service a game that is almost 6 years old at this point, and its original codebase was ported from a previous flash game, then everything else was built on top, there are a number of classes like monster, etc that are over 7000 lines long lol
Also, there is no particular reason to optimize things if you do not have any issue in term of perofmrance.
this one seems like a reasonable optimization and is pretty normal to do
Same. hierarchy depth of 4-5 class of multiple thousdands lines
You might want to use DOTS
If you are going for high enemies counts
I would but too invested in this one now D:
honestly usually I find the worst tech debt comes from when somehow something really hacky got snuck in a year ago and no one noticed and now like half the codebase is built on top of that, and fixing it would require refactoring almost the whole thing
Then you gonna deal with the limitation
So you just keep piling more hacky workarounds and fixes on top of that and it just gets worse and worse cause your PM will never approve the 2 weeks of work to just fix the damn root problem, so instead everyone keeps piling the "workarounds" on top of the pile D:
Unity (GameObject) does not support well high numbers of enemies.
You have a long road of performance optimization and decision to do.
i recently rewrote a core system in the game to seperate it out from an existing nested spaghetti code class since the design team wanted to keep adding and changing shit with how it worked, and it was becoming super unmanagable to the point any time anything touched it, bugs would start cropping up. But now we gotta spend a bunch of time testing the rewrite since the original tied into a ton of systems all over :S
I hope to have some time to do the same at some point. Even more because we are reusing the same code base for multiple project.
And yes, I know, it is costy to do so.
yeah, it seems like endless pushback the moment i sugest we rewrite anything lol
It is kinda hard to prove the $$$ values it gets.
but every so often the tipping point is finally reached where the amount of money going into keep something that is super broken going outweighs that of a rewrite lol
and yeah, project lead/company stakeholders are all about not putting dev time into anything if it isn't directly marketable to the end user ๐ข
Even more when you have people that are king at what they do and they always find out a way to make something work fast.
I think the solution for that might to incorporate a minimal amount of time in "Maintenance" project each iteration.
Just gotta come up with an estimate of, on average, how many man-hours get burnt messing around with workarounds, compare to how many man hours it would take conservatively to fix it
I find once I can convert it into tangible concrete numbers like, "Every week we waste about 5-6 man hours working around this problem, it would take about 35 man hours to fix it" suddenly approvals come a lot easier :x
the higher ups were all like "dont waste dev time writing tools since by the time the tool was written you could have already finished the task" i basically ignore that and write tools all the time, and they have saved me literally weeks of dev time at this point lol
I'm trying so hard to push for a build machine
higher ups also do tend to get so focused on the time spent and forget the whole "yeah but this makes our devs not want to quit their jobs and need replacement every 2-3 months soooo..."
A fucking build machine
I'm like writing small bash file to automate building on the side.
"this will cost us about 30 hours of work... but our devs will stop fucking quitting because the job wont be a hellish nightmare of onboarding so... you do the math on that one"
we have a build machine that every time a new merge is done into the build branch it spits out a build and a download link in the company chat so anyone can pull it down and use it for whatever
At some point Im gonna make myself a build machine for my personal projects
It is like the most important things you need
I'm still fighting to have one and have time to setup it.
Ideally what Id like is to decouple the build system from my git repo. I know normally the two go hand in hand but Id like to actually keep em distinct as systems
its nice cus marketing/etc dont use git and every so often they need a build do capture footage or qa needs one to test, etc.
Yeah, I'm gonna need to push more for that.
I'm looking at my colleague making a build for 30min each two days
Doing a lot of error in doing so
I posted this over in #archived-code-general in case any of yall know the fix for it, I think I borked something badly. Or at least Rider borked stuff up with its automatic fixing of things
#archived-code-general message
Regenerate solution ?
Is that this one here? I was about to ask if thats what I wanna click
Yeah
lets give er a whirl
Might want to clean up what you have also
Sometimes, you can close Unity and reopen.
Maybe deleting Library can help
yeh that was it, thanks!
np
so i was looking at that example you mentioned of the model view pattern, and started writing my own implementation, still pretty early stages at the moment, one thing i changed from your example was making my own version of these, since the original used classes which were allocating memory each time the events were called, not much mind you, but as a project gets bigger and some properties are changed on hot code paths, it can begin to add up.
Can probably drop the sender part too tbh
and then you can even drop the entire struct to just be a string right? I think you can make a delegate have an in value?
seems possible, ill have to do some more testing
public delegate void PropertyChanged(in string propertyName);
Ill test this out
It looks like it works yup
does appear to work you just need to fully define it in the callback
I use a handy wrapper method to simplify the process and add automatic Type safety :3
@obsidian coyote this is the latest iteration of what I have, I havent added support yet for Enumerables but I plan to at some point
https://hatebin.com/nqrqpnayus
And then an example implementation would look like this:
https://hatebin.com/rohpgvblvq
And then you just subscribe to it via:
GameState.Bind(g => g.UI.SomeIntValue, OnSomeIntValue);
public void OnSomeIntValue(int val) { ... }
outa curiosity have you tried building your code with il2cpp compiler? i know some aspects of reflection, etc are unsupported by it, wondering if this all works within what's supported
I have not tbh
Itll prolly explode in its current state, I expect I will need to do a lot of fixing to make it work if I want it
ah fair enough
@obsidian coyote aight for now I put all of the necessary code in one single gist here, which means if anyone finds fixes or optimizations or whatever they can even fork and open a pull request.
I think later if it gets big enough that a single file is just not enough, Ill break it out to a full blown github, but for now it feels small enough that 1 single .cs file is still valid (barely) for all the code to make sharing easy
https://gist.github.com/SteffenBlake/ace74a893d0b16c30a7eb2a42d6d9230
maybe im skimming and missing it, but one thing that could be considered is something like this where you can notify a change on on things that depend on other things
I would let the subscriber handle that part
If the subscriber cares about both of those fields, then I would have it subscribe to both fields.
If you want logic where like, setting Max Health automatically "caps" health if its greater than it, then I would add have that logic exist in the service layer that manipulates MaxHealth and Health
One nice thing is my logic supports subscribing to not just 1 specific member prop on a "leaf", you can subscribe to an entire "branch" of the tree.
As an example instead of needing to do:
GameState.BindTo(m => m.Player.Health.Current, OnHealth);
GameState.BindTo(m => m.Player.Health.Max, OnHealth);
You can just do
GameState.BindTo(m => m.Player.Health, OnHealth);
And if any value "beneath" Health changes, it will fire the event
I've not really been watching any of this convo and am just dropping in after randomly clicking on that script, but what is this for ๐
None of this will work in IL2CPP will it?
None of this will work in IL2CPP will it?
I have no idea, I havent tried it, I dunno what makes or breaks this
ive tried some of the stuff and it works, havent tried pixxel's exact code tho, just my own version
LamdaExpression stuff, it's surely so reflection-based it won't build ahead of time
Mostly its a question of whether this code works or doesnt work in IL2CPP:
public static string GetFullMemberName(this LambdaExpression memberSelector)
{
var currentExpression = memberSelector.Body;
if (currentExpression is not MemberExpression memberExpression)
{
throw new Exception("Member Expressions only!");
}
var name = memberExpression.Member.Name;
while (memberExpression.Expression is MemberExpression next)
{
memberExpression = next;
name = memberExpression.Member.Name + "." + name;
}
return name;
}
I dont think this actually uses reflection, its utilizing the lamba expression as a normal object
my version doesn't use lambda expression stuff at all
Like all its doing is just looking at the lamba object itself and "stringifying" it
I think System.Linq.Expressions works in IL2CPP
I guess the other thing that might work or not is this:
public void BindTo<T>(Expression<Func<TSelf, T>> selector, Action<T> method)
{
var fmn = selector.GetFullMemberName();
var compiled = selector.Compile();
var concrete = (TSelf)this;
PropertyChanged += (in string prop) =>
{
if (prop != fmn)
{
return;
}
method(compiled(concrete));
};
}
Particularily this line:
var compiled = selector.Compile();
At least, base on this post: https://discussions.unity.com/t/il2cpp-compiled-expressions-performance/235306
Also, binding can be done with ILWeaving.
If you really intended to go hardcore, you might want to look into it.
Im not sure what that is, but in my case the event is a string that represents the "path" to the property, and the expression just serves 3 purposes:
- "Hard Types" the method so we can automatically correctly bind in a typesafe way to the matching Action, note how I dont need to cast to a
Tin that logic - I serialize it to a string which should match the same "path" value of the event. If it doesnt, something went horrifically wrong
- I compile it as a "getter" to actually get the value and pass it to the action
ILWeaving means to generate the codes (IL instruction), reducing even more the "boilerplate" and removing the limiation of IL2CPP.
I dunno how the performance of this is compared to [CallerMemberName] magic we can use
Are you saying to weave before Il2CPP compiles it?
I am not a fan of that sort of "post compilation" injection of code because now you cant debug that easily
That is what I heard at least
In theory, this code does not needs to be debug that much.
What I have there has pretty small amount of boilerplate per property, I feel like this isnt too bad:
private AbilitiesState abilities;
public AbilitiesState Abilities
{
get => abilities;
private set => BindChild(ref abilities, value);
}
private int roundCount;
public int RoundCount
{
get => roundCount;
set => Mutate(ref roundCount, value);
}
as an example, it's pretty light, and the upside is it is 100% debuggable and doesnt involve any particular magic stuff, it "just works" exactly as is
Well, whatever is landed on I'd want to be extra sure it compiles with Il2CPP if anyone aims to be using platforms that require it
I can try testing that out, whats the process I would do to test how it runs in IL2CPP mode?
Building with it enabled
I wouldnt be surprised if it doesnt work, but I also bet there may be workarounds to get it to play nice with it
IL2CPP can be a really pain to deal with.
The expression trees implementation used for AOT platforms is an interpreter, so it is pretty slow.
https://forum.unity.com/threads/are-c-expression-trees-or-ilgenerator-allowed-on-ios.489498/page-2#post-6416774
So it might just work, it'll all just be interpreted in the end
ive had pretty good success with it, except with the webgl il2cpps stuff, seems to throw memory issues all the time :S
It has strange limitation.
its super annoying, i pretty much just gave up on webgl builds all togeather since they seemingly only ever produce errors ๐คทโโ๏ธ
I got a couple normal bugs from my latest set of changes, lemme hammer those out and then Ill see how badly IL2CPP breaks my stuff lol
As stated by vertx, it is pretty slow. So you should profile the performance more than if it works.
as long as whatever is using the slow code is cachable, i think its ok
since its being done in a bind call, im assuming the result of the compile call is reasonably fast, even if the act of compile isn't
ooof
The slow code would presumably be the output from the generated expression, compile would be as slow as normal (as in, both are slow to compile)
It only runs once per binding on startup, it "saves" the output of it since it never will change, so shouldnt be noticeable.
same for the .compile() calls
The output is interpreted though, that's the point
it's not like IL where the output is an actual compiled function, fast as it would normally be
its a string to string comparison during runtime after the initial startup so should be fine for that part
oh like, what it produces isnt a "normal" Action<T>? hmmm, that may be impactful, we will have to see
Hi, does anyone here have experience making more intelligent enemy AIs using finite state machines and/or behavior trees? I am making a 2d top down game (think behavior like among us) and I was hoping that I could make AI that would accurately emulate a player. I have made basic patrolling and sentry AIs before with navmesh but I have never tried to make anything smart
Was just wondering where I should start with all this
i wrote an interpreter that i made to let people write scripts to control tanks and pit them against eachother, effectively my "compile" generates a closure containing nested closures that are setup as an abstract syntax tree, its performance isn't too bad, defiantly not native but considering its executing hundreds of nested functions i also wouldn't call it "slow", guessing the stuff produced by .compile() can't be much worse/better
As with anything I imagine it matters at what scale it's used
thats fair, if EVERYTHING uses the pattern in a larger scale game, it could become a bottleneck
Most of the time, those are enough. There is other approach though such as https://learn.unity.com/tutorial/setting-up-a-goap-environment
I know this is a question that is hard to answer, but how difficult would it be to develop a somewhat intelligent AI that could be close to indistinguishable from a player in a game similar to among us? Basically would two experienced programmers with CS degrees be able to figure it out in a week haha
yeah that's a pretty bad question lmao
Nothing. You need more than a couple of week to be able to do that.
Gotcha. I'm under a bit of a time crunch so I was just checking if it's something that I should even consider or not
Just collecting the various data to make something like that could take month
Makes sense
If your game is simple, I guess you might be able to use a probabilistic model though. Something like https://en.wikipedia.org/wiki/Expectationโmaximization_algorithm
In statistics, an expectationโmaximization (EM) algorithm is an iterative method to find (local) maximum likelihood or maximum a posteriori (MAP) estimates of parameters in statistical models, where the model depends on unobserved latent variables. The EM iteration alternates between performing an expectation (E) step, which creates a function f...
lol, these are very different things, you can easily make something that tries to kill an enemy when there is no one else around, but to try and "think" about how to do it in a way thats clever is a much more difficult problem
It is just a question of chosing the correct value function
Either you try to imitate something or try to win.
ya personally I don't think ML is as important as nicely setup state-machine behaviour in such scenario
but if you have that as a base you could amplify it quite a lot with ML and optimize paths based on other parameters
e.g.: positions of others, amount of players, previous votes per players, completed tasks, etc
yeah, you can achieve a lot through a basic state machine, also easier to get the exact behavior you want without pouring tons of time into collecting data and training.
imo ML might be worth investigating if the problem is not well defined, or there is no reasonably clear "solution", but i think for most peoples use cases that is overkill
@austere jewel Oh so uh, turns out I have been on IL2CPP this whole time, I guess it works!
And you have built the game, right? Not just complied in the editor
I have not! Lemme try that :3
IL2CPP only compiles C++ when you build, in the editor it's all just mono
tbf in such scenario a properly trained AI would outperform a state machine, but yeah getting data for it would be a pain..
especially when it's not as simple as getting data in text or image form.. but I think state machine alone should be enough
my lil test game runs at 260-280 fps with a mono build, but around 480 fps with il2cpp ๐ฅ
doesn't even have to be super-intelligent, likely.. so yeah killing 2 birds in one stone xD
now THAT'S overkill xD
nah, its a user scriptable game, so if the user scripts are slow, i need to make sure the base game is as fast as possible to accomodate that lol
Anyone know why TMP_Text accepts a char array as input if it just turns it into a string internally anyway... I was trying to use a char array buffer that i dynamically replaced chars in to prevent string allocation, but it seems TMP just strings it anyway according to the deep profiler ๐
if it just turns it into a string internally anyway
It doesn't
i've used that before and indeed saved the gc
hmm, maybe ill have to give it another go then
looked like it was causing allocations anyway when i tried last ๐คทโโ๏ธ
show your code perhaps
i dont have the exact code anymore since it didn't appear to work, but here is an example.
afaik that "Should" just keep updating the first char in the array to a random value between 0 and 9, then updating the tmp text via SetText(char[] arr)
might be something wrong in this contrived example since i just threw it togeather, but it appears to work ingame as you'd expect
@austere jewel aight, looks like it fails, whats my best option for getting logs from an IL2CPP build to see whats failing when I publish it?
does unity handle logging out to a text file by default, or am I gonna need to setup some kinda hook to capture thrown exceptions at runtime somehow and log em out to a file
It logs to the editor log file, and the console
if it's published, then it logs to the player log
logging locations are pinned to #๐ปโunity-talk
Is there a good guide you know of so I have my settings correct and am running the IL2CPP version in the editor, such that I can replicate this occurance?
Also appears to happen when using the specific "SetCharArray" call, but that shouldn't be surprising since it appearst to just call that internally if the input is a char array anyway ๐คทโโ๏ธ
To debug a Unity Player running on an Android device, connect to the device using USB or TCP. For example, to connect to an Android device in Visual Studio, select Debug > Attach Unity Debugger option. A list of devices running a Player instance appears.
Is this talking about the Unity Remote app? Or is this talking about something else entirely?
its annoying the docs just namedrop these terms and dont provide any further info about wtf a "Unity Player" exactly is
unity player afaik is just the actual built/running game on the device
the tmp code ๐
ah guess they ghosted me.. oh well
@austere jewel oh sick, I got it working now, debugger ftw
So turns out not only do you gotta do zenject's whole deal of enforcing [Inject] on all your class constructors that inject, but you even need to make sure you have empty constructors with that attribute even on injected classes that are "leaves", that dont inject anything
if you do that, it works, looks like at least my chunk of code is working totally fine for IL2CPP, it was just Zenject that was breaking cuz my couple "leaf" injected classes lacked that necessary empty constructor trick to make sure they got included in the build
but aside from that, all the stuff I shared in my gist appears to be totally kosher with respect to IL2CPP, Im not noticing any issues
Can someone understand why there's major slowdown when I return to the first menu? The more I repeat this the longer it takes to get back.
@obsidian coyote it indeed doesn't -- you can check the source from the package, rendering is done in a per-character basis last I checked
oh u did.. sry was scrolled up ๐ yeah it stores as char array and gives you the option to get the string out of it
lol np, it seems like it shouldn't but for whatever reason it allocs a new string, seems like it sorta defeats the purpous of a char array input ๐
umm well myStr += "x"; allocates a new string as well, so
I guess they could've used a stringbuilder but is it really worth it?
would be REALLY nice if you could toggle some mode or w/e that prevents the string alloc so you can manupute the chara array directly and not worry about mem allocs for stuff like fps couters, or other stat based things
stringbuilder still creates a string
it only allocs the string once you request it, no?
no? :S
I mean.. not each time you 'append' things to it
no not each time, but once you want to get the result of it, it does
for stuff like FPS counters, or health bars, or other stats that update frequently like weapon hit accuracy, or damage, etc. using a char array and just updating the chars in the array to the new value woulda been nice to be able to do, instead im stuck creating a pre-allocated lookup table for a large range of numbers to prevent the allocations
well I've created a input field using TMP as renderer
no reason you can't do it with TextMeshProUGUI as well ๐
(it's hard time for english but hope u got what I meant xD)
even storing just 2 digits of percision on a decimal number, 100,000 strings in a lookup table only gets you up to 999.99 numeric range :S
(yeaa.. even harder time for math.. I'll just take your word for it XD)
either way TMPro has nice internals for rendering, generating and utilizing fonts, etc
you should be easily be able to create an optimized FPS counter
yeah, it does, just sucks they don't give you the option to write to the char array directly without creating additional memory each time :S
probably an oversight from their end.. I don't see any reasons to alloc string when you set char array
but given the popularities of SetCharArray(..) and text_get() methods, I don't think it's unreasonable
also, it's probably optimized as an all-in-one package including input fields and stuff. I think they're quite a small team
apart from that, my game has no memory allocations once its running, unless the object pools need to alloc a new item, but then its saved for the next time its needed, so in my case its annoying lol
high-level UI code contains tons of todos, comments, and duplicate code.. wouldn't surprised if their not-best-engineers took on some of those tasks instead
as for health bars, text aside, here's smth interesting: https://github.com/fholm/unityassets/tree/master/PerformantHealthBars/Assets
drawing health bars just using the unity canvas and a slider works well enough, as for performance, if you pool them, they seem fine and don't appear to allocate any memory
well yeah the VertexHelper approach is if you REALLY care about performance -- like if you wanna render thousands
are you sure this is called in builds? it looks like the only time it would be called in a build is when reading the text property back. The other calls are editor-only
hmm let me see
but for millions some compute shader for calcs, along with fragment shader for rendering at the appropriate position would work best
ah you might be on to something
Can someone understand why there s major
cool, does look like the char[] option on tmp doesn't actually alloc the string when its a build ๐ฅณ
Quick Question: Unity player setting has a option in Resolution and presentation by name "Render over native UI". I need this setting to be turned for a specific need; but as sson as i turn it on; any image /font or any game component that has alpha lesser tha 255; will start displaying actual screen of the operating system;
guessing the render over native ui literally means use the system desktop as the clear buffer, so it soulds like its working as intended, why do u need it?
does anyone know how to instantiate the default builtin unity textmeshpro inputfield through code? this is without creating a prefab manually and saving it to my assets. my first approach was to simply add the TMP_InputField component to an empty gameobject but as you might assume it didn't work. only the component itself was added while everything else is missing. font assets, background sprites, etc, etc. I found the following code online from a forum post GameObject go = TMP_DefaultControls.CreateInputField(GetStandardResources()); which is supposedly from the unity source code? but idk how to get the standard resources that's supposed to go in the createinputfield method
I googled that line of code and found the method that does that in like 2 seconds https://github.com/JackDotGriffiths/Geta-Game-Jam/blob/43091ef970be2574205e3185fca4d58607e03d3f/Geta Game Jam/Library/PackageCache/com.unity.textmeshpro%402.0.1/Scripts/Editor/TMPro_CreateObjectMenu.cs#L94C1-L118C10
oh so the method is private. interesting. so I can just get it through reflection
I'm curious as to why you want to do it without just putting it on an object in the scene or making it into a prefab? If you want a purely code driven UI, unity does have this. https://docs.unity3d.com/Manual/GUIScriptingGuide.html
I'm modding a game so that's why I'm trying to do it through code. I don't have a scene to add to. I could create a prefab but then I'd need to create an assetbundle, embed it into my project and load it. I just want to do it through code
that's the gui layout. not relevant
That's editor only
the immediate mode gui is not just layout, it allows you to drive the whole ui if u want, its the original way unity ingame ui's were done before the whole canvas style ui
do you think the asset paths exist in build? because then I could just copy the method into my own code
I don't wanna make a custom ui. I just wanna instantiate a tmp inputfield
what methods? assetdatabase?
Yes
hmm
immediate mode gui is just a thin wrapper around the c++ library unity uses called imgui, and u can make a simple input field with it ๐คทโโ๏ธ https://docs.unity3d.com/ScriptReference/GUILayout.TextField.html
I know there's Resources.GetBuiltinResource but idk if that can be used to access any of the required assets. probably not
you don't need the methods, just the resources. Copy pasta that code, set sprite references, generate the struct it needs at runtime
yes but the question is whether or not I can access the resources at runtime
Worth trying, forgot about that existing tbh
you need the sprite references. You just need some way to get them in the first place that doesn't rely on editor methods. I would create a SO and populate the references there personally
like this: https://gdl.space/ayesejinaq.cs
as expected I can't load the sprites from the given paths using Resources.GetBuiltinResource. idk if there's a way to list al the built in resources (not from the assetdatabase of course). but it seems to be able to instantiate the inputfield without sprites. but I'd still like to get it working if possible
sorry I don't understand the purpose? what is happening? it gets the asset and then loops over them? idk what you're refering to when you say SO
you grab the references to sprites and store them in a SO. Then at runtime or a build, you create the struct that TMP_DefaultControls.CreateInputField needs
- Create the SO asset
- Go to Tools/Get TMP Resources to auto-populate those fields
I just did
that looks like you're looking at the script
did you create an instance of the SO?
your screenshot is not looking at the right thing
but can I even get an use the asset's references at runtime? I mean when it builts those default assets are not included in the build?
so even if I have the references they won't point to anything
everything you reference is included in the build
idk how I create an instance
Create > TMP Resources SO
I'm not building from this. it's for modding. the game I'm modding is already built. I won't be the one controlling the build
that seems like an important detail you forgot to mention
nothing you reference will be included unless your mod loads the references itself, so it'll still work fine if you're making an AssetBundle
I thought I had already mentioned but I think I mentioned it in unity-talk when I was first trying to get help there. moved to this channel because the other one wasn't helpful
so at the end of the day I need to create an assetbundle with the resources I require?
or find them at runtime in some way, and I can tell you from experience that would be very tedious if you want to do anything of significance. Sometimes it's easier just to hijack some existing element yourself and repurpose it if you're not building something huge
yea maybe I can use the background sprites and such from existing input fields. would also make sense to keep the same style
only problem is the input field I created using CreateInputField doesn't seem to have a caret and idk why. I did try to copy the caret from an existing input field but that didn't work
hey; so, I just realized a Trigger in animator is left checked until it's used. so, if you set a trigger named Jump, this Will not be unchecked until it's consumed by a state node
so, any idea how best to achieve a real trigger thing? something that gets checked for just one frame
Bool that you toggle off in the next frame
nah its a user scriptable game so if the
is it possible to build a file downloader that downloads files simultaneous using the parallel job system?
or will i likely run into some problems using this method.
Quick question
Is it possible to use unitys ECS outside of unity?
Like within a .net console app?
I'm currently using a 3rd party one but would love to use unitys. I don't care about burst or jobs, just the ECS code
No
Figured
UnityWebRequest is already multithreaded (except on WebGL)
Went to sleep actually ๐
But yeah naturally the ToString creates a string
How to increase mesh rendering speed/fps?
I am doing procedural generation mesh
I have rendered the hexes individuals and combined them to make a tile map like system
you have 2502 batching
the answer is - static batching or the SRP batcher, depending on your render pipeline
ok thanks
@plucky laurel hey, how are you, I have designed my FSM just like you suggested and its much better, but I have one problem, I dont know where to store some of my variables
some variables need to be shared between transitions and states
i guess one solution is to put those into a seperate class but i dont think thats very elegant
I'm not .cache, however what you describe is a really common issue. What you are doing with FSM at the moment ?
And which state needs to have share data.
hi
i have an fsm for enemy ai
i had a problem where a state and a transition needed to communicate
i mean share a variable
i actually could fix it by having the transition handle the logic, but i just got lucky with the solution this time
i dont know what i would actually need to do if one of my states needs to share a variable with a transition
both state and transitions are abstracted
The transition should be able to read the state ?
A transition would be specific on a given state.
TransitionFromAToBInCondition
Transition would know about a and b.
yeah it is able to read the current state
So, what is the issue ?
sometimes the variable that needs to be shared is not state specific
so reading the state wont help
Where is the variable then
so I have an FSM and I have an Enemy2 that derives from the fsm
the variable is in enemy2
an FSM should be a component of an enemy
enemy shouldnt derived from it.
Not every enemies need an FSM
public class Enemy2 : FSM, IDamageable
Let's stay on the subject, what about the variable
so if the variable is in enemy2
i cant pass enemy2 to the transition, as that wouldnt make the transition re-usuable
for example if i have enemy3
In that case, interface would be the solution
i will get an error
Also, you wouldnt have this issue if you had made 1 enemy class.
Which is how you probably should do things
how would that work
for different behaviours
public class Enemy2 : FSM, IDamageable, IEnemyThatCanBeUsedInStateBecauseIDecidedToMakeMultipleClassOfEnemiesThatDoNotDeriveFromASingleClass
oh instead of FSM you think it should derive from enemy?
Prefarably you would do:
public class Enemy2 : Enemy, IDamageable
Then, your state can work with enemy
i had this idea yes
You can also do a cast if necessary.
if(enemy is Enemy2) then...
It is not something is recommanded
yeah no thats ugly
Bad pattern. But it is possible
thanks for helping out
I'm looking to have my player be able to visually pick up objects. How would I map their hands to the object?
You position the player at a given position, play an animation, then refine the touch with IK.
thanks ๐
Hey, anyone know a better way or know why i have the problem ?
When my Character was created, i use playfab as a CharacterData DB.
Code should be clean but when i have more than 10 keys and Values in my Dictionary, i got a console error message from playfab with "InvalidParams".
public void CreateDataStructureForPlayFabCharacterBlock1()
{
var request = new UpdateCharacterDataRequest();
request.CharacterId = characterID;
request.Data = new Dictionary<string, string>()
{
{"Forename", characterData.foreName},
{"Lastname", characterData.lastName},
{ "Age", characterData.currentAge.ToString() },
{ "Current Position X", characterData.currentPosX.ToString() },
{ "Current Position Y", characterData.currentPosY.ToString() },
{ "Current Position Z", characterData.currentPosZ.ToString() },
{ "Currency Gold", characterData.currentCurrency1.ToString() },
{ "Currency Silver", characterData.currentCurrency2.ToString() },
{ "Currency Copper", characterData.currentCurrency3.ToString() },
{ "Minimal Level", characterData.minLevel.ToString() }
};
PlayFabClientAPI.UpdateCharacterData(request, OnUpdateCharacterDataSucceed, OnUpdateCharacterDataFailed);
}
Thats the code, how it works... with more Values ---> ERROR
Read the documentation of Playfab. Look at the error code. Look into the forum. Try to update in two call.
Playfab will return more info than just "Invalid Params"
for example
{
"code": 400,
"status": "BadRequest",
"error": "InvalidParams",
"errorCode": 1000,
"errorMessage": "Both username and email are required unless specified with RequireBothUsernameAndEmail."
}```
the error message should have more details
I done this all... thats the thing... The Documentation is very rar and uncompleted.
I tried in 6 calls a 10 Params but after 3 calls i got a "service unavailabe"
The documentation should be pretty explicit. You also probably limited by the amount of call you can do per seconds.
And as stated by PraetorBlue, the error should contains more information.
Okay, yea... i guess thats the problem... I have the free version with limited calls maybe^^
UnityEngine.Debug:Log (object)
PlayFabManager:OnUpdateCharacterDataFailed (PlayFab.PlayFabError) (at Assets/PlayFabManager.cs:489)
PlayFab.Internal.PlayFabUnityHttp:OnResponse (string,PlayFab.Internal.CallRequestContainer) (at Assets/PlayFabSDK/Shared/Internal/PlayFabHttp/PlayFabUnityHttp.cs:220)
PlayFab.Internal.PlayFabUnityHttp/<Post>d__12:MoveNext () (at Assets/PlayFabSDK/Shared/Internal/PlayFabHttp/PlayFabUnityHttp.cs:159)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)```
You can literally look at the error code and see if this the case.
That is not an error code.
But this is, that what i get. o.O
It is not....
Read the documentation if you can't figure out how to access an error code.
you're passing in OnUpdateCharacterDataFailed
in other words you get to pick which function runs when it fails
and in that function you can definitely access all these things
{
Debug.Log(result.Error.ToString());
}
you mean that... right ?
right see how you're just printing Error.ToString()
you can also print errorMessage
or errorCode
etc
yea, and thats the way, how i log my errors.
aaaahhh
/Client/UpdateCharacterData: Invalid input parameters
Data: Too many keys specified in Data dictionary update. Limit is 10 and request contained 57.
UnityEngine.Debug:Log (object)
PlayFabManager:OnUpdateCharacterDataFailed (PlayFab.PlayFabError) (at Assets/PlayFabManager.cs:489)
PlayFab.Internal.PlayFabUnityHttp:OnResponse (string,PlayFab.Internal.CallRequestContainer) (at Assets/PlayFabSDK/Shared/Internal/PlayFabHttp/PlayFabUnityHttp.cs:220)
PlayFab.Internal.PlayFabUnityHttp/<Post>d__12:MoveNext () (at Assets/PlayFabSDK/Shared/Internal/PlayFabHttp/PlayFabUnityHttp.cs:159)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)
Anyone know why AudioSettings.dspTime would run faster than Time.timeAsDouble?
DSP Buffer Size is 1024 and my FPS is 90, so Update() is happening ~twice as fast as audio buffer updates.
But the same exact results occurred even with Buffer Size set to 256.
`Start(){
int delayUntilCheckpoint = 1;
double dspCheckpoint = Audiosettings.dspTime + 1;
double timeCheckpoint = Time.timeAsDouble + 1;
double checkProgressTime = timeCheckpoint - .05; }
Update() {
if(Time.timeAsDouble >= checkProgressTime){
Debug.Log(timeCheckpoint - Time.timeAsDouble);
// Returns ~.04 as expected
Debug.Log(dspCheckpoint - AudioSettings.dspTime);
// Returns ~ -.08 consistent negative value. Expected result is a positive number }}`
If I make the checkProgressTime .2s before the checkPoint (instead of .05 in example), the DSP comparison will (barely) be a positive number.
So why would the Audiosettings.dspTime be so far ahead of Time.timeAsDouble..? I would have assumed it's because it updates the buffer every .2s (1024 dsp buffer size)
so it "jumps ahead" instead of incrementing linearly like Time.timeAsDouble, but the issue happened even with smaller buffer sizes, so..
!code
๐ Large Code Blocks
Large code blocks should be posted as links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/
https://paste.myst.rs/, https://hastebin.com/
๐ Inline Code
Surround code with three backquotes. Not quotation marks.
To get C# formatting the first line should only contain cs or csharp.
Add a comment with a line number if there is an error message.
```cs
// Your code here
```
Do not share screenshots of code unless requested.
The audio system has its own clock, separate from the game clock
it also won't respect Time.timeScale
Also, you gotta use OnAudioFilterRead if I am correct.
It does not update at the same moment of the standard Update
any way to set a custom transform matrix for an object? not seeing a clear way in the api
I'm trying to skew the vertices of a standard MeshRenderer dynamically
Just tried it in an actual build, and it worked much, much better. ๐คทโโ๏ธ. Gotta be better at trying stuff in builds before spinning my wheels
you can use a shader, or a matrix4x4 to multiply with the vertices of your mesh
Is it not possible to apply this on the unity side, through changing the localToWorldMatrix? that would allow the use of any underlying shader
(also recalculating the mesh data would be waaaaaaaaaay too slow)
Vertex Displacement or Compute Shader
thats why i recommended shaders, if you dont need like colliders changing too then theres no downside
y'all I really don't need to use either of those, I'm just trying to get around the fact that Renderers don't let you easily skew vertices, even though they totally could
The totally do ?
Also, renderer has nothing to do with the mesh.
we just provided u the different ways of skewing a mesh, how do you not need either of those when your problem is skewing a mesh
you can change the localToWorldMatrix to do the same thing with much less effort and processing
It's just a readonly field on Renderer
which is the problem
hmm maybe you want to use a projection matrix on your camera instead then?
that would affect every object, so not quite
you can have separate cameras
if you set a non-orthogonal matrix for the model transform, then the vertices will be skewed in some way
Yeah, with a projection matrix.
You can do the same in a shader
You can use whatever matrix you want.
Do whatever you want with the position of the vertices
I'm not asking for alternatives rn, is there a way to set it in unity?
I know how to use shaders to accomplish the same effect, which I will do if there are no alternatives
This is the way in ANY engine.
This why graphics card have been invented
To process the position of the vertices and other things
I don't think you understand me
I would like to modify the existing localToWorldMatrix that is then passed to the shader, so the existing shader code can work with no modification
Then modify the positon of the renderer
What is so hard with that ?
transform.positon = MyPosition;
you can't skew a mesh like that
localToWorlMatrix is not skewing a mesh then.
By your terms.
Because localToWorlMatrix is that.
it could if you could set a custom one
Yes, the positon of the renderer.
If you want something else, you create a variable in shader
Then you populate it.
This is how it is done.
it doesn't have to be a rigid transform (only translation, scale, rotation), , it can be any 4x4 matrix
Shader that use the matrix, will expect it to have properties.
Anyway, what you want is a shader.
maybe there's something I'm not understanding
is there some secret rule that the transformation from model space to world space has to be rigid and otherwise stuff would be bad?
I guess I could just make a small rewrite of MeshRenderer
Before doing anything, study what is being done.
but then I probably couldn't use SRP batcher
hmm I could also overrride the default MaterialPropertyBlock, that would work too (and also not affect other game engine code I think)
Why are you so determined to not write a shader ?
But are ready to skew with other things that are not made for that.
because I would like this to apply to any object, regardless of the underlying shader (which should work)
otherwise a shader variant is necessary for every kind of object that has this effect applied
I'm not using an uber shader
you can pass whatever matrix you like into the low level drawing methods (Graphics.RenderMesh is that the right API? it's been a while since i did it) so that might be the way to go
This is more of a general programming question for algorithms but I'm implementing it in Unity so language specific terms are needed. I'm designing a system to allow a user to build a structure in 2D space. They can place pipes with bends, joins and straight pieces. Each piece is "square" and fits in a 1x1 area so coordinates (1,4) can contain 1 pipe of those variations. I was considering storing using classes for each coordinate that has something placed then store all the pipes in an array (an array of created classes). Firstly, is that the best way for speed? Given they are pipes, how could I calculate the internal volume of them using this system? For example, I need a function to say "Is (3,6) connected to (4,1)"
Do you need performance ?
depending on how much different behaviour there is between different pieces you could consider just storing enum values in your grid, and if you do want your parts to have their own classes then you probably only need one instance per type and all the coordinates using the same piece can reference the same instance?
Yeah, I've been working on that before actually programming as it could be really bad to do some of the stuff I need at high frequencies
Ah that's an interesting approach
Do you need performance ?
{
"type": "straight",
"health": 100,
"x": 0,
"y": 0,
"neighbors": [
{"x": 1, "y": 0},
{"x": 0, "y": 1}
]
}
I was going to store it like this (With some changes) to keep track of neighbours
Ah, I see
That sounds complicated ๐
This is also a bad idea for performance.
You better off with a grid.
(If it is not too sparse)
Also, why you need to specify neighbors ?
You can simply define the actual pipe cant you ?
And, you would better be off using a bitmask
For the pipes to contain "pressure" so some way of checking if one pipe has a "leak" then decrease connected pipe pressure. But there would be shut off valves at places to stop total leaks
The user could go 1000 pipes in one direction but 10 in the other so would the grid be fixed size?
[Flags]
public enum Neighbors {
North = 1 << 1,
West = 1 << 2,
South = 1 << 3,
East = 1 << 4
}

Fixed size would means like 1000x1000 which would be a couple of MB.
Alright I have a rough idea on bitmasking thiny. To just clear up how the pipes work, they are of fixed shape such as straight, bent, T or 4way and don't adjust based on neighbours
If you have like 10000x10000 then you have a couple of 100 MB.
Sure, you can keep track of every possible pipe in an enum as well.
You can even have 2 fields
One for the type and one for the rotation
Hmm I see, would that be easy to calculate "is connected"?
you could probably break that down into chunks to save allocating all the big empty areas too
Ah that could be another bit
Yeah chunks for only constructing a specific amount on screen at once
Not all the pipes else it could lag
Yes, you could. It is just that you can no longer "simply" use a grid at this points.
Having all of the pipes in the scene at once could be an issue, especially if they need to make calculations like pressure
You just need to run any graph algorithm about connectivity.
Right
In mathematics and computer science, connectivity is one of the basic concepts of graph theory: it asks for the minimum number of elements (nodes or edges) that need to be removed to separate the remaining nodes into two or more isolated subgraphs. It is closely related to the theory of network flow problems. The connectivity of a graph is an im...
There is a ton of resources.
It is really a well documented subject.
I see, so I can't just check if it's connected upon creation and store that value for both the created and each neighbour?
Depends what you mean.
So basically, the player can "place" pipes in a grid cell
for pipes on a grid, you can probably go a long way with a boring old flood fill
Yeah, pressure is important and idk if Unity can just simulate it
This is also a type of connectivity algorithm.
It can't
ah.
So for overall architecture still, no classes? Start small with something like 10x10 area and store every tile?
Even if it's empty?
For performance, yes.
Keeping in mind memory allocation.
You might need other method.
Hmm
However, an array is the best in term of performance.
10x10 chunks still feels important
10x10 is nothing
A 2D array?
Yes, a 2D array.
Right
Just to throw in an extra complication, 0,0 is the center, and it has - coordinates preferably
I would consider chunk to be 1000x1000 in size.
No issue. You can just have relative position in your grid.
Also, if 1000x1000 is pretty much your whole grid, then I would not even consider using chunks.
I will consider using dictionary unless player can place lots of pipe, 1000x1000 maybe wasting lots of memory though accessing is faster than dictionary or even a quad tree
Yes 1000x1000 would be very large. They would really not need that much to start, but it could be a lot of growth late game
At the end of the day, it matters what is the size and how sparse the thing is.
a dictionary is definitely the easiest way to start something like this, your grid is infinite that way, but depending on how your game logic needs to access it, you might run into performance problems sooner
Then, you might want to sacrifice some performance for memory.
20-50% filled where they are
Not that sparse
Well it wouldn't be 50% of the entire grid, just where they build
So for example, they make a small set of pipes in the middle starting area
20% is not sparse.
It wouldn't be 100% full
that small central area that is "busy" would be like 50% full
How do you code out a slope system like in character controller for rigidbody
You could always have a chunk for growing up.
By following a youtube tutorial
suggest one
So like a smaller area for where they start?
Then they can build out further later?
So just like a {} of the different parts?
very helpful
you literally gave me a google search link, which I didnt ask for
So, you are not even about to click on the video tab of google.
your keys would be coordinates and your values would be whatever you want to put in your tiles, since only the occupied tiles use memory you can get away with putting more per tile in a structure like that
how could you assume that I didnt do that earlier?
{
"(0,0)": {
"type": "straight",
"health": 100,
"x": 0,
"y": 0,
"neighbors": [
{"x": 1, "y": 0},
{"x": 0, "y": 1}
]
},
"(1,0)": {
"type": "bent",
"health": 80,
"x": 1,
"y": 0,
"neighbors": [
{"x": 0, "y": 0},
{"x": 1, "y": 1}
]
},
// More pipes can be added here...
}
Like that?
Because you asked
I asked how to code out a slope management system just like that one in character controller FOR rigidbody
like i want character controller level code
And, I said to you that you can just watch a video because it is way more explicit than any answer we can gve you and that there is ton of video and blogs on how to do it.
and then i said to suggest one video/blog that will be helpful
you gave me a google search link
;-;
something like that, hopefully the tile doesn't need to store its own coordinates?
You donโt have to store the coordinate of neighbours ,they can calculated in run time simforces have shown you you can use one-char number to represent neighbours
It is literraly open source.
Nah, it should have it as the key
but as an example
From my experience the vertex should store it coordinate in graph
This feels like it would be slow for 1000 pipes or so and new builds
it's going to be slower because if you need to go through the neighbors, each one needs to be looked up in the dictionary, but you can work around that
for example you could store your tile instances separately in a list too and instead of storing the coordinates for neighbors you could store their indices (if you don't mind doing some extra work every time you recalculate the neighbors)
Indicies as position in the list?
yeah
What if something is added to the list? like a new pipe
It just goes at the end?
And this isn't risky to go wrong?
You just use bitmask to check if neighbour in one direction exists then calculate it coordinates ,you can calculate how much memory one vertex needed
Right calculate direction of neighbour. I might as well go back to the enum and not worry about what "type" the neighbour is and just say "connected to a pipe in the north" like earlier was discussed
[Flags]
public enum Neighbors {
North = 1 << 1,
West = 1 << 2,
South = 1 << 3,
East = 1 << 4
}
how you store the neighbors is kind of up to you, but if you need to fetch the actual tile by its coordinates a lot, that's slower to do with a dictionary than if it was in a grid where finding something by its coordinates is super fast
depends on your game though!
It is still arguably fast though.
Surely a dictionary with the indicies as the key is fast?
Yes, but it is less fast.
Cache miss, hashing, collision
So a grid will be faster, even with TONS of empty space?
Always
It is just a question of memory.
hashmap indexing is the same speed as array indexing because a hash map is an array under the covers
Btw The neighbour should be 1<<0 to 1<<3
One to one mapping vs many to one mapping
Which can be solve with other method
There is none ?
That's not my enum code lol. Never used it before
uh, that's not true
If all the bits are zero then no neighbours
Oh, yeah my bad 1 << 0 = 1.
I still haven't got a final conclusion of grid or dictionary. I feel dictionary would work better as 99% of space will be empty even for the most extreme player
Might better to just use:
[Flags]
public enum Neighbors {
None = 0,
North = 1,
West = 2,
South = 4,
East = 8
}
1,000,000 tiles and they will barely will 1,000
You can also have multiple grids
Like the chunks yeah
if you can't decide, it's easier to start with a dictionary and switch later when you need to optimize
That would create other issues such as calculating pressure across chunks
Alright thank you!
Dictionary final answer
Then neighbours with enum
but it's impossible to say where your performance problems will start until you make the rest of the game ๐
well you'll need some objects as your dictionary values i assume, not sure how the json fits into it!
Ah right c#
I uhh
Javascript
Anyways Back to the C# world
idk where to even start lol
Potentially make a new script for storing the data in some type of manager
Why not just store the pipes as vectors
A single straight pipe that is 1 unit long or 1000 units long shouldn't use any different memory, it's just a vector + origin
Because they are "components" with T parts and 4way connectors, each built seperately
That's fine, how you store it doesn't change
Jumctions can be stored seperate from the pipes themselves.. but is there a reason you even need to support them building a T junction that has 1 part unconnected?
Why not make an elbow turn into a T automatically when a third pipe is connected
For this game, it wouldn't be suitable
How so?
There aren't long straights, lots of bends and the pipes don't necessarily touch because they are neighbours
That's fine, what I said still applies
An origin+vector is still way less data almost always
I am very confused on how this would work
There's theoretically a "worst case" scenario that maybe makes storing every cell individually be as bad
If you have this, you dont need to store "Theres an intersection in the middle", thats already something you can implicitly discern from the fact the vectors intersect
No matter how long/short those lines are, that still just takes 4x Vector2s. Each line is just 2x Vector2s (1x Origin + 1x Offset)
Yeah I get that
You can effectively just treat each one as
struct Pipe {
Vector2 From;
Vector2 To;
}
Right but what if it turns at every cell in a diagonal step pattern?
Thats the worst case scenario effectively
What about forks?
What about a loop of pipes?
What about it? A square is 4 lines
You just define each turn?
basically yeah
As in a very long complicated loop
The topographical result is not really relevant to how you store/process the data
Actually this may running into trouble when running dfs, you cannot effectively distinguish the neighbour of vector
what do you mean?
And modify neighbour as well
We were talking about pressure and stuff right?
Most games dont treat each individual "unit" of the pipe as a seperate entity, but instead would typically handle each "length" of the pipe as a single thing
Kinda my thoughts
Although it's pipes, they aren't really long pipes, just small squares that connect
Yeah that should just be handled as how you render them, but for actual logic I would take a more complex topography like this and treat it as such, where each colored "strip" of pipe is a single "thing" and you just track which pipe "segment" connects to which other pipe segment(s) via a Dictionary<Segment, HashSet<Segment>>
the lengths of those segments can be arbitrary, like the bottom right square could be huge and top left one small
But Id just treat each Corner -> Corner "strip" of pipe as 1 single "thing"
And I thought I was lost before we added the colours ๐คฆ
It still feels like it may be better with the dict
Now if there's like any kind of interactable or like, special placeable thingy that can interrupt or change a pipe, Id also consider that a "break" in the segment, like so:
I dunno if you have stuff like that but I think I read something like that
Each color is a single "segment" which can be anywhere from 1 to many tiles long
But how can you get the segment player interact with in O(1) time
its just a lookup table
I really appreciate the idea, but I think it's a little complicated to start
Though I believe it can get within O(log n)
Given a coordinate and a set of edges represented by pair of vector2int determine the edge coordinate located at(it may be none)
Id just keep updating an overhead service with a lookup table of Child -> Parent
The only hard part is actually handling "splitting" a segment
Thats what I forsee as the largest challenge, if you get that part worked out its home stretch after that
Right so I have the actual data structure, but how should I actually make this code? A new blank file specifically for structure management? I already have the script for placing the pipes
What do I attach it to? The same as the empty controlling all the built parts?
Well in my case typically I only have about 1% of my logic "attached" to monobehaviors personally
99% of my logic isnt "attached" to stuff and just sits inside of my game engine's stack of POCO services
Splitting the segment by give two points is actually finding two points at same or different segments
So just a blank C# file, do I not need start and update? I'm very new to actual unity programming.