#archived-code-advanced
1 messages Β· Page 100 of 1
static batching is just some optimization for culling after you have your mesh data, and chunked it accordingly.
beyond static batching you also have gpu instancing from the shader, but you can't have both enabled
so well, each grass is anyways an individual gameobject
and each is marked static for batching
shouldn't this be moved to GPU anyways just to have more performance?
one thing though is static batching is resolved at runtime, so yeah it's a little hard to work with on the editor
I mean i generate grass positions at runtime based on current density param
just the positions
I swear i can let GPU do that in parallel
and then also let gpu cull stuff if it's possible
It's up to profiling to compare if static batching is better than GPU instancing, but from my testing I usually do use static batching for non-moving meshes and GPU instancing otherwise.
is grass counted as moving tho
i mean it might have wind as part of vertex shader
so it kinda displaces itself each frame based on noise
GPU instancing may be better then, but I need to check again to see if vertex manipulation does break batching
Im just extreemly noob at grass coding
but my initial idea was to have terrain as cell combination, which is streamed to player at runtime
It does not
and so each time cell should load, i calculate random grass positions on the terrain and objects placed on it
Oh nice. In that case could be better for mobile haha
so well, some objects might support grass growing on them, and some don't
Itβs also how TABS & co can play animations on millions of objects
(Shader based animations)
and then based on this information and density param, i just render random grasses all around the cell
and then come the grass lod and frustum culling/distant culling problems
which idk how to solve properly
like sure, each frame calculate distance to each grass pos and change mesh to lower one or even ignore from matrix
but fps falls to 20 or 5
Culling stuff is just something you usually balance with chunks
but doesn't unity use frustum culling on individual gameobjects by default
like a built-in feature
even if they are spawned at runtime
right, so this is what static batching help resolve. It'll cull indepedent objects, but still draw it all in the least amount of calls as possible
This video showcases the GPU frustum and occlusion culling capabilities of GPU Instancer. The terrain details in the video are rendered with GPU Instancer's Detail Manager.
GPU Instancer is a Unity asset that increases performance when rendering extreme numbers of objects on the screen.
For more information, see: http://www.gurbu.com
Asset Sto...
otherwise individual gameobject renders is one drawcall each
https://www.youtube.com/watch?v=jw00MbIJcrk
Guys a memer but he uses some alg to cull in a similar way
While billboard grass is a performant, easy option for visualizing grass, modern games like Breath Of The Wild are able to utilize real geometry to get more interesting and appealing foliage. How can games nowadays afford to do so?
Support me on Patreon!
https://www.patreon.com/acerola_t
Twitter: https://twitter.com/Acerola_t
Twitch: https://w...
but dude worked for nividia so he's usually got some good ideas
i watched all 3 of his grass videos
it's all computed in the shader which is ideal, but it's his alg at the end which makes the video
but too crazy to me. I think a few more drawcalls and chunks is fine and let frustum culling do the work
if fps is higher than 140 on my pc then yeah, a few more draw calls is fine
but when it's 20
π
this stops before it gets interesting
all his videos are like that
it's like wow cool waves but really how
anyway, solving the "indirect" bit and the "culling" bit in a performant way is so non-trivial that you can just stop attempting it unless thats what you want to specialize in, programming/dev wise
bite the bullet and get one of the assets, you're just reinventing the same code anyway if you DIY, this is a solved problem and its somewhat weird that its not a base engine feature
also, if you want to DIY, you can also use vfx-graph to render grass π
that's sad
well, if there is any opensource code which does exactly what i want, i will gladly use it in my project
hehe
lez go
"This asset needs shaders capable of indirect instancing. Such shaders can be hard to obtain, and a full tutorial on how to obtain those is provided in the Github page. However 1 shader suitable for HDRP is provided allowing to display grass with wind deformation."
that will also be true if you DIY, comes with the territory
instancing is only half the rent, you also need to shade the vegetation nicely π
What does Unity's terrain usually do anyway? Chunk/Frustum too eh?
and you need to be quite careful what you do there because of the many instances
I'd really suggest trying some Mesh builder and generate a SDF of a terrain then build your meshes in chunks
probably the easiest mid solution for decent performance + add on some static batching for trees
the terrain is already a SDF of sorts
I've found it alright for generating a ton of grass, I just think the UI/tools a little dated
true
but adequate to make trashy steam polluting shovelware π
you can go very far with the unity terrain if you replace basically everything except the auto LOD π
actually the problem with unity terrain is IMO that once you try to go big with it you run into way worse engine limitations than just grass rendering
try loading open world chunks smoothly LOL
well, if chunks are small, it's not a big deal
try building a game with 100+ chunks (takes forever)
how small though... there is a tradeoff
well, you'll still get frame drops even with 256 chunks
basically what happens between 90% and 100% in the async load blocks the main thread
it's also lots of objects which should be spawned ig
you can time-slice your start functions and instantiate all gameobjects manually after the load to spread it out
i render first cells around the player while he is on loading screen
but that is just very inconvenient and complicated and should be part of the engine
and then when player goes to another cell, i cut the ones which are not in range and spawn new ones
yes, but that alone doesn't get rid of the hiccups
i can probably let them spawn one by one
but yeah, instantiating a single 256x256 terrain mesh might take time
well, in any case, you can do a lot of work around the fundamental engine problem, i just think this should not be neccessary
also there is no tool support for it, its just a pain, and slow π¦
what if i spawn a flat plane or smth and then give it several seconds to curve using the height map
player won't rly notice anyways
if you're really dedicated i think you can make a streaming system that incrementally loads data and instantiates and displaces stuff
but thats akin to building a custom engine
so what's the point?
well, doing a moddable game
which supports terrain changes
each changed terrain gets packed to an asset bundle, and then game overrides references when user starts it
sounds like a non-fun problem to have
well, i wrote a lot of editor code already
the biggest problem rn is image/audio implementation
writing an audioclip to a bundle and then loading it for modder to use
rn my code allows me to unpack any bundle and drop it's contents to Assets folder
so it's like a "dependency", which is written inside the mod description
except audios and images
ScriptableObjects were the easiest
Model Prefabs too
Hi guys, what would be the best way to create a map transition system in which I have a chained list of maps?
Points about the system:
- It will be possible to move forwards and backwards in the maps.
- Scenes will be in different files
- And there may or may not be dynamic loading of the assets in each map, depending on whether the player moves forwards or backwards.
Consider using Loading Screen to make it easier to manage. If you really do not want loading screen, you could use Additive Scene.
I might just be being stupid, but can someone explain why the following code isn't working? I'm trying to get a Game Object to move in the direction that it's facing.
rb.velocity = transform.forward.normalized * speed;
I've tried debugging transform.forward, but it is always equal to (0,0,1), regardless of the Game Object's rotation.
I've tried debugging transform.forward, but it is always equal to (0,0,1), regardless of the Game Object's rotation.
If it's (0, 0, 1) then your object is not rotated at all
This is a #π»βcode-beginner question
also there is no sense in normalizing transform.forward
it is already a unit-length vector
oh i'm so dumb i meant to put this in general, my mistake
but well i'm here, i've tried debugging rotation as well and the value is changing
so the object is in fact rotating
The object this code is running on is not the object that is rotating then
show your log code and what was printed, etc
rb.velocity = transform.forward.normalized * speed;
Debug.Log(transform.forward.ToString() + transform.rotation.ToString());
Outputs: (0.00, 0.00, 1.00)(0.00000, 0.00000, -0.18319, 0.98308)
you're logging a quaternion
correct
Debug.Log(transform.eulerAngles)
if anything you're probably rotated on the z axis
which is just a roll
which will not affect which direction transform.forward is
should i do transform.eulerAngles instead of transform.forward in the first line?
it outputs: (0.00, 0.00, 1.00)(0.00, 0.00, 183.24)
yeo
like I said
your object is still facing directly forward
it's just rolled
The code is working perfectly
oh i see what you mean
what can i use so forward isn't based on the z axis but instead x or y?
the z axis is always forward
that's nono negotiable
maybe explain what you're trying to actually do
is this a 2D game?
yes
If it's a 2D game then "forward" is usually right or up
so you want either transform.right or transform.up
the red arrow is transform.right
the yellow/green arrow is transform.up
(when you have an object selected and have the move tool on)
forward is the blue arrow
alright that works, thank you
which for 2D games usually just points directly into the screen
and sorry about putting it in the wrong channel
I have a file which contains optimized vertex data as :
UInt8 [bitsize = 8] = VertArray, NormalArray, BoneWeightArray, trianglesArray ```
I'm looking for a dev who can write a script which can load this optimized mesh in unity by converting the UInt arrays to Vectors2, Vector3, etc
If anyone is intrested in doing this job please text me back, I'm also willing to pay a good amount for this.
!collab
We do not accept job or collab posts on discord.
Please use the forums:
β’ Commercial Job Seeking
β’ Commercial Job Offering
β’ Non Commercial Collaboration
why Unity.properties doesn't generate partial PropertyBags for abstract types? (annotated with [GeneratePropertyBag])
Can someone forward me more information about the structs going to the stack instead of the heap as an optimization step? I cant find something tangible regarding Unity.
For more details;
I read from somewhere that initializing Vector3s inside a Update is not as expensive as creating a class, and that Vector3s are like for example floats since they are structs, that they dont generate garbage.
this has nothing to do with Unity really
it's just the difference between value types and reference types in C#
Much appreciated, I'll read them through.
how do you serialize a graph object which contains references to monobehaviours that are always in the scene ?
i have nodes which are game objects with a node class but the graph itself uses dictionaries so won't just remember the data
if i just store the raw data, the issue then when i deserialize is the nodes are already gameobjects in the scene so how do i get the data back to them
add component (or reference the existing one) then load the data back to the class?
huh?
you might need to be a bit more descriptive
the nodes are already in the scene so when the graph deserialises it needs to inform the nodes about their connections so they have connection info
how you serialize the graph? adjacency list or edge list?
build the adjacency list first then you have the connections of each vertex
public void OnBeforeSerialize()
{
_connections.Clear();
List<INode> nodes = new();
List<INode> neighbours = new();
_graph.GetAllNodes(nodes);
foreach (var n in nodes)
{
neighbours.Clear();
_graph.GetConnectedNodes(n, neighbours);
foreach (var neighbour in neighbours)
_connections.Add(new Connection(n as Node, neighbour as Node));
}
Debug.Log("Serialize " + _connections.Count);
}```
like this
then on deserialize im trying to load back in the connections and link them to gameobjects already in the scene
this is edges list
yes the edges have a reference to the two node game objects
when you deserialize it you get the edges list back, do you have a hashtable or any other mappings that allows you to get the gameobject back from based on node identifier?
this is not how you deserialize but how you get the node gameobject in world back based on some data
when you first load the graph you must know how many vertices the graph has then create the gameobjects
the graph has a dictionary for adjacencies it holds a reference to a monobehaviour
the issue is how i link that back to the object in the scene on deserialize
private HashSet<T> _nodes;
private Dictionary<T, HashSet<T>> _edges;
this is in my graph object
neither can be directly serialized
isnt each vertiex has its own unique identifier?
since _connections will be an array of Connection (node A, node B) these are references... would that still link the right game object on deserialize
well the reference is the identifier and they implement IEquatable
public sealed class Node : MonoBehaviour, INode
where
public interface INode : IEquatable<INode>
reference can be identifier since they are address and address is unique.... but also got changed when the application closed and open again
i would separate the data about the vertex and gameobject, since you wont deserialize the whole monobehaviour, and i would assign the unique identifier to gameobject and vertex pair
eg i have a graph
vertex id: neighbor
0:2 3
2:
3:1 2
1:
and i would store an array of
index 0 1 2 3
GameObject A B C D
once i deserialize the graph then i use the vertex id and array index to access the gameobject in the array and load the data back to gameobject
if you need to load other graphs and no enough gameobjects in the array, instantiate more
the issue is the graph needs to reference INode interface so just storing IDs is not ideal
seems like i need to handle the link between game objects and ids in a monobehaviour that manages the graph then
Not sure if I remember correctly, but I was using scriptableobjects to store the information, as those are persistent files
SOs are good but i plan to add to the graph at run time so still need to save but you can't really save to SO at run time right?
you can , depending on your data, save it and overwrite the SOs default state at runtime with that serializeddata
hmm why must this be so confusing
what data you store in the file?
i mean you can include one more field to identify each vertex if not exist
then provide the vertex id to gameobject mapping
you cant use reference equal only to identify different vertex otherwise i have no idea how you store the edge
I am wondering, if your handling of data and gameobjects is the right way to do. If you edit it on runtime, the nodes should store all info about the gameobjects and update them on runtime. Not mirror their data
i showed you how i store it in the dictionary
im probably doing it wrong im not sure lol
the graph object just takes an INode type but because its dictionary and hash sets when i recompile the data is lost
So you are not storing anything anywhere yet?
You got the code for that?
but you are not (de)serialize the whole monobehviour since you implement your interface
sure i use the ICallbackReciever with this bit of code:
[SerializeField]
private List<Connection> _connections = new();
[Serializable]
public struct Connection
{
[SerializeReference]
Node _a, _b;
[SerializeField]
string a, b;
public Node A => _a;
public Node B => _b;
public Connection(Node a, Node b)
{
_a = a;
_b = b;
this.a = a.name;
this.b = b.name;
}
public override string ToString() => $"{a} -> {b}";
}
public void OnBeforeSerialize()
{
_connections.Clear();
List<INode> nodes = new();
List<INode> neighbours = new();
_graph.GetAllNodes(nodes);
foreach (var n in nodes)
{
neighbours.Clear();
_graph.GetConnectedNodes(n, neighbours);
foreach (var neighbour in neighbours)
_connections.Add(new Connection(n as Node, neighbour as Node));
}
Debug.Log("Serialize " + _connections.Count);
}
public void OnAfterDeserialize()
{
Debug.Log("Deserialize " + _connections.Count);
foreach (var connection in _connections)
Debug.Log(connection);
_graph = new();
foreach (var connection in _connections)
if (!_graph.TryConnect(connection.A, connection.B))
throw new Exception($"Failed add connection {connection}");
_connections.Clear();
}
Sounds to me like the mono is just resetting as they are recompiled, which makes sense.
Yeh, I would take that whole data part away from the mono and use something persistent like an SO with save and load functions or what not.
right but is my approach wrong here with using Node refernces?
would the reference still be valid when re-opening the engine
if its not wrong ill have to do a <int,GameObject> setup
but that would require a re-write of my graph object at this point
reference is inconsistent across different life time/cycle
btw you can refer to some real world example of how to storing the graph in plain text and think how you would load it to your application
right but i need to figure out how to find the node in the scene when loading it back in if i cannot use node reference
hows that relevant to unity serialisation issues ?
and i would store an array of
index 0 1 2 3
GameObject A B C D
use vertex id as key and assign a gameobject to each vertex, reuse the gameobjects when loading a new graph
your problem is not about where the graph comes from (yes you can load a graph from internet or ram, file system is just one of the sources) but how to load the graph to your world (hence how to store it)
so my graph now has to return a node id aswell
yes, you can use string btw, as long as it is unique and you can associate each vertex with its data
actually i guess maybe something like this:
[SerializeField]
List<uint> _ids = new();
[SerializeField]
List<GameObject> _nodes = new();
[SerializeField]
private List<Connection> _connections = new();
[Serializable]
public struct Connection
{
[SerializeReference]
uint _a, _b;
[SerializeField]
public uint A => _a;
public uint B => _b;
public Connection(uint a, uint b)
{
_a = a;
_b = b;
}
}
so the serializer only cares about ids not the graph
Again, I wonder why you store the gameobjects instead of creating a dataset of nodes. And from that dataset, you create the gameobjects with the relevant data
because the node gameobjects need to know their connection data when i load the graph in
they already exist in the scene
No, your node dataset needs to know the ocnnection
exactly what i want to say....
wdym
separate the data from gameobject and monobehaviour using a struct or class (but your monobehaviour will store it)
Imagine a database with two users in a mulitplayer game. Those are stored on the database and created on runtime. If you add a new user, you first create that user on the database and tell all clients to create a gameobject with the name of hte player coming from the bdatabase. You dont throw in a new gameobject, tell the server to copy that gameobject to all clients and figure out something locally. Same goes for your dataset nodes. You have the database storing all connectinos, positions of the objects and what not. And in runtime, your scene will take that data and create the gameobjects out of it.
and if you want to add something on runtime, you still can create a new gameobject with ocnnections and pass all that information to the database back.
but the nodes are already in the scene as static objects so creating them on deserialize doesn't make much sense to me
having example is much better than my answer
so reuse the gameobject
You said, youw ant to create more on runtime
how do i find the specific gameobject for the specific node data in the graph without using GameObject serialize?
ok yes those would be created
but the rest are already present
you need a object pool
when the graph is unloaded then recycle all the vertices back to the pool
what you wanna tell us with that comment. That you dont want to redo it? π
no i dont understand how instantiating them would help because then i can't just add them to a scene during level design id have to add the data to a graph rather than add the node to the scene which is harder to level design by ?
or im not understanding what you're trying to say π
second π π
Let me try to rephrase it. So, lets start from, what is your node graph actually doing in the end? what is its purpose?
the graph contains a hash set of all nodes (INode) and all the connections. it also checks with the nodes if a connection can be made (INode) contains things like CanConnect(nodeB) etc
connections are in a dictionary
Thats not the question π
What is its purpose, not how does the code structure work
other than that its just storing that data for which i can get info from
for any kind've waypoint setup i need
Ahhh, waypoint system, got it
And you want to set waypoints in runtime for units lets say, and if you save and reload the game, you want those waypoints to be persistent
short: dont use reference or try to serialize any kind of reference (they are pointers and not persistent), use other stuff to identify each data
yeah but even the non runtime isn't persistant at the moment
the static stuff
so not even GameObject?
dont talk about graph now, you want to store some data of some npcs so how would you identify each npcs? ofc its name or id
then when you store it you save the npc data with its name or id
when deserialize it you create a gameobject (or get it from pool) and load the data back
now replace "npcs" to "vertices"
but if its a static object already in the scene creating a new gameobject would mean i have now got 2 in the scene one relic with no link and a new one that does
maybe i should not make Node : Monobehaviour, INode instead just have Node : INode ?
Yeah, I can imagine. They will reset to mono default state everytime unless its a public variable or something. So, thats why, store it apart from any scene related stuff. If you setup a waypoint, the code would do
User Clicks to set waypoint => (pass in the transform values, pass in the unit its related to) The system creates a waypoint visually in the scene and also adds a node to the database => Saves the data. From there reloading, you check for the player file/database, recreate the units from savegame and recreate all nodes depending on that unit.
ok but what about waypoints already in the scene before the player did their runtime stuff
do i have to create the graph but not have those gameobjects in the scene than on play it adds them?
thats kind've odd
You might have a scene datatable/object that stores the scene, premade units or premade waypoint lists. All depends on your game data
gameobject is just the view of your model
You can still write your own level editor and when you create a gameobject and add the monobehaviour RuntimeNode for example to it, it will trigger your nodemanager to add it tot he database and save it.
imagine this simple scene. right now graph holds a reference to these 3 Node classes and the connections ignore the little blue circle. if i save just raw data great, but now i load the raw data those 3 nodes need that raw data assigned back to them. thats why i was using reference but reference as mentioned wont persist if i close unity
As we said in many different ways π Do not hold the DATA inside your GAMEOBJECT. The gameobject is just a placeholder for your data.
so should i have something like NodeObj : Mono
and in that have a Node : INode struct lets say which holds the data?
i dont understand how to link them
you should have a database/json/scriptableopbject or whatever that holds the data for all nodes. You define, what a Node is, what values does it have.Vector3 for position, Node inComing and Node outgoing nodes? Whatever you prefer
right now how in that image above would the game object of node 0 be linked the data in scriptable object ?
when i deserialize
How to avoid from colliding nav mesh agent with each other? When I reduce their radius to zero (close to zero), they are fluctuated
simply said like
public List<WaypointPath> waypointPaths;
public class WaypointPath
{
public List<Node> nodes;
public void AddWaypointNode(Node node)
{
nodes.Add(node);
node.incoming = nodes[nodes.Count -1];
SaveToSomeFileOrwhatNot();
}
}
public class Node
{
public Vector3 position;
public Node incoming;
public Node outgoing;
}
and then you could just serialise that whole thing to a file. And when you want to create a new node, you just trigger the addwaypointnode from your scene when you create a gameobject with a specific RunTimeNode class. The rest of how you handle input of the user is another story
This is written in discord, so please dont take this code 1:1 π
im not seeing how this would then tie to a pre-existing object in the scene so the object can update its visuals based on the waypoint data
jesus π YOu are really stuck to having that premade scene stuff tied into the database
well yeah all the data is in one graph
the graph is your scene?
public class Node{
public Vector3 position;
public Node incoming;
public Node outgoing;
public NodeObject nodeObject;
}
public class NodeObject:Monobehaviour{
public Node nodeData;
}
now the node know which gameobject it is assigned to
You gotta let go the idea, that you are doing the node creation ion the scene. You just creating visual representations of the nodes in the scene, but the values for them are stored in a dataset
Eating milo powder taste goodπ
im trying to but struggling to get my head around it at the moment π
ill first seperate node from monobehaviour inheritance
maybe that will highlight in my mind how i can then move forward
I would just try out the idea, we suggest to you on an empty scene. For now, you could even just create an empty project and prototype. Doing nothing in the scene for now, just trying to create a dataset, for ease of use, a scriptableobject, add some waypointpaths there and then try to recreate simple gameobjects even primitives out of that data.
that should clear your head if you do not get into your current code while trying out. Just to get the idea and then figure out, if it works for you and how you can adapt it to your current code π
i might have to ping you tomorrow or something if i still get stuck π
Not sure Ill be available, but you can try π there are more people willing to help π
Is there a way to write a script that looks at the terrain layer and changes the layer... i.e. grass every where and a dirt road. I want the dirt road to be on a new layer called walkable
What layers are you talking about?
circled
These layers are per gameObject. And your road is part of the terrain, so it can't have a separate layer.
That's what I figured.. I just thought there might be a way to script something that would separate the 2...
What are you trying to do?
Why do you need the road to be on a separate layer?
i want to make the road walkable
Is it not walkable now?π€¨
I want it to be the only walkable area
I put together this but not sure `public class TerrainTextureDetector : MonoBehaviour
{
public Terrain terrain;
private TerrainData terrainData;
private Vector3 terrainPos;
void Start()
{
// Get the terrain data
terrainData = terrain.terrainData;
}
void Update()
{
// Convert player position to terrain coordinate system
terrainPos = transform.position - terrain.transform.position;
Vector3 mapPosition = new Vector3
(
terrainPos.x / terrainData.size.x,
0,
terrainPos.z / terrainData.size.z
);
// Get the texture mix at the player's position
float[,,] alphaMap = terrainData.GetAlphas
(
(int)(mapPosition.x * terrainData.alphamapWidth),
(int)(mapPosition.z * terrainData.alphamapHeight),
1, 1, 0, terrainData.alphamapLayers
);
// AlphaMap to determine the dominant texture?
// Main texture here?
}
}`
but that was something for when i was working on a survival game walking on grass vs dirt to change the sound
Walkable by what? Navmesh agent?
I was trying that, but navmesh, navmesh surface, is new to me, so I was trying to break it into something I knew... basically I'm trying to create a TD game, I want the walkable area to be the dirt and not grass... in the past I used cubes that I sliced down to 0.1 and created a grid... trying to not do the grid thing
How are you gonna move the entities(characters? enemies?)? That's the important part.
enemy start
follows path
when given more than one path determine the path of least distance
determine path with least possible damage based on towers on screen
change course if tower upgraded that changes the math of best course
continue path
follow path to end
You could compare your position on your worldgrid to the painted texture on the terrain, if I am not completely wrong? Like the painted texture is the "minimap"
Probably this could be accessed and depending on black white or whatever there is in the texture, you know if its walkable or not. not sure this is the best practice of restricting the player
What path? I still don't understand how you are going to move the enemy?
Maybe navmesh could also be used here instead of trying to figure out a path from textures
that's why I am trying to separate the road from the grass so the enemy can only walk on the path, if i separate the path into a new layer called walkable I can set a start and end waypoint for walkable
navmesh maybe the best way to go, but i am not very familiar with it yet
I would look into this as comparing textures and stuff might not be the most performant way, when calculating a path that can be dynamic with several values considered like towers and what not
you could still try to create the walkable paths with some complex code from a texture and bake a navmesh area out of it, but not sure if thats worth it if you could just handcreate simple borders
which channel should i move this question to then... is there a navmesh channel?
not sure #π€βai-navigation is meant for this. Mods might have a better suggestion here
from pinned messages, that might be the channel for you
this is a simple example of the terrain, the full version will have many more dirt path options
I posted in that channel already and got no response so I changed my thought of how to do it
I would go to the ai nav channel, ask there. And get some insights first. Then you might struggle with code and can come back here if needed π
ye, depending on the topic, it might be to complex or difficult. So it would be your task to split it up in parts that you could ask for
I mean I can create a grid that does what I want, but its not how I want to do it... I want the dirt path to be walkable and the grass area to not be..
You might make a list then why you want it or if its just you stuck in the idea for having it π
lol
yeah but where do i post my list?
i can see the whole game in my head.. I could draw the game in about 20 minutes,
The list of why you want it? Thats just for me to be sure what the benefits are
you gonna be online for a bit?
I am hopping on and off as I got time. No guaranteed opening times on my side π
You can bake navmesh areas based on predefined areas. Maybe just create some editor script which detects the change grass/pathway then have it roughly place these areas on the terrain. Bake the navmesh yourself once and done
Nothing else really to do unless you completely separate path and grass. This basically means recreate the path and place it on top
I'm making an RPG with races and classes that implement an interface and used in game. Since they are pretty much entirely defined in code, how can I make my game mod friendly so people could program their own races and classes
If you want your races and classes to be extendable, you might need to get rid of hard coded races and feed them through some kind of list that you can extent for example
if you're targeting mono, you can load an assembly at runtime from a bundle or file path, then find the types loaded by that assembly that implement your interface
Is it possible to load C# scripts from a directory so they could put new ones in there?
no, they need to be compiled into assemblies
unless you want to ship a C# compiler in your game!
Which is actually more doable than it sounds, since Roslyn, the most popular C# compiler, is itself fully written in C#, and can be included in a Unity project as a .dll + dependencies.
That makes sense. How does something like steam workshop work into something like this? I'm pretty new to modding as a concept
yeah, off the top of my head space engineers does this and i'm sure there's others, but there's pros and cons
obviously, prebuilt assemblies will be faster to load!
and a damn sight easier, how to handle compile errors for example?
This seems like a dumb question but I have been digging through API/SDK docs for UGS analytics for the better part of 45 minutes now..
How do I set the ApplicationVersion for analytics events?
that guy - clientVersion
https://docs.unity.com/ugs/en-us/manual/analytics/manual/track-events (page doesn't have any info on setting default parameters or how to change them)
OK, nevermind, it seems like it's pulling from Application Version - in the project prefs dialog.. which I guess makes sense. π€¦ββοΈ moar coffee
is there a way to use bee building system using the cli without opening unity editor ? I need to build to android but unity editor crash
I can't use application. Data path outside mono constrictor ( it needs to be called in awake or start methods although sometimes unity allows for that strangely enough like it complains depends on its mode lol) ,
I've a variable needs to be a static therefore I can't have multiple instances of the same type .. but the challenge here is that I need to determine the folder path based on the platform I cant create two static string but the method which I pass the string-s into is static too now .. how I can overcome this?
Make a static method that you call and it returns the correct path
You can also use preprocessor directives
//shooting
if (Input.GetMouseButtonDown(0)) //left-click
{
Instantiate(projectilePrefab, projectilePoint.transform.position,
Quaternion.identity);
anim.SetTrigger("Shoot");
aud.PlayOneShot(shootsound);
} I dont know why but my projectile is always going left instaed of right please help
Well, the only thing that could be relevant to that issue is Quaternion.identity and the prefab being rotated oddly. None of this has anything to do with the projectile moving at all though
Also, #π»βcode-beginner
This is definitely not an advanced issue
It's the movement of your bullet. Spawning doens't have to do anything with it
So I tried to make a backup of my project however it sent it to the recycling bin. I was able to restore my game and the code, but the code isnt working at all
Can anyone offer any help?
Not really an advanced issue. You should be using version control for your backups, take this experience as your proof as to why.
No one can really help because we cannot be sure if you've restored every script, the correct scripts, meta files and all that would be necessary. Surely theres something specific that's not working that you can debug and see where problems are.
Okay thank you. Even when I make new scripts they dont work
I dont know if that narrows it down at all
"Dont work" is about as vague as it gets. Try specifying, probably in the beginner or general channel, about what doesnt exactly work. Right now based on your description all it sounds like is you create a new script and expect it to do something by itself
So basically as a test, i made a new script with just a public string variable because i would know if the scripts were working i would be able to edit it
And assign it a value
But not even that pops up
The class name is the same and its a mono behavior
You'll need to share the actual error and details on where you see it. A screenshot would do for starters. Because after all the messages, it's still not clear to me what the issue is.
ive been trying to come up with a good architecture for a bullet hell combo manager. Essentially I want to have a system where it's easy to tweak which moves a boss uses in what order so I can mix and match (and potentially reuse moves so they can be used by the player or other enemies). But I'm kinda unsure how to abstract this. My plan was to be able to have something like instruction sets, so a list like
[ShootCircle, Wait(2), ShootNova] that I could inject into an enemy and have it perform those on repeat or with some logic of its own too. My problem is that if I make this too abstract, and have it be a list of Skills, it becomes hard to parametrise all skills. E.g.
//Pseudocode
foreach(instruction in instructionlist){
instruction.execute();
}
Becomes a bit of a problem if an instruction like ShootCircle wants to be able to use the enemy's damage number.
Does anyone know any reading I can do for a system like this, or is the architecture inherently flawed and trying too hard to loosely couple things
I suppose one option is to just pass the enemy (or player) script into the instruction and have the instruction retrieve whatever it needs, although for commands like Wait(2seconds) thatd need to be pre parametrised or something
if you want to go all in on the interpreter design, you could make it work like a stack-based interpreter and add push instructions that add data to a stack, then (for example) ShootCircle would pop x number of data items to get its parameters
I'm not too obsessed with this being the approach necessarily, and I don't really wanna over engineer. I was just trying to think of how to have fast iterations on enemy behaviour without defining that behaviour on the enemy itself since that to me sounded like i'd require different scripts each time I wanted an enemy to have a different order of moves.
There might be a better way of doing that than to express every single possible action as an abstract instruction, I'm not too familiar with gamedev architectures though so kinda unsure in which direction to look for this
i feel like there's quite a high bar here at which any nicely abstracted system is saving you any time vs just throwing a different script on each enemy type and writing out the order in code and/or dropping in a visual scripting graph to do the same thing
Yeah most likely
A pattern I've used in the past to solve a similar problem to this is to use [SerializeReference] to serialize a list of instructions/actions. You can serialize whatever parameters you need this way, such as:
[Serializable]
public class WaitInstruction : Instruction
{
public float Duration = 2;
public override void Execute()
{
// wait {Duration} seconds. Execute method probably needs to be a coroutine or async method.
}
}
You just need a property drawer to be able to select instruction types in the inspector, like:
https://github.com/mackysoft/Unity-SerializeReferenceExtensions
or https://github.com/vertxxyz/Vertx.SerializeReferenceDropdown
You could also serialize a reference to the enemy or player, but in my case, I was already using a dependency injection framework in my project, Zenject, so I could also add injectable dependencies to these serializable classes.
Thanks for the confirmation. Was just looking into this myself. After reading all the options from BuildOptions I found the WaitForPlayerConnection option. Cheers internet person π§
I'm looking for information on some memory stuff in Unity. Let's assume that we have List<Sprite> and List<AudioClip> in a SO in an assetbundle. When you load that SO, does it load all the sprites into memory immediately? The same with AudioClip. AudioClip has Load/Unload Data functions, so I don't know if it loads the compressed stuff into memory before Load/Unload is called or what. I saw no such thing for Sprite or Texture2D, so I'm not too sure about that. The main problem here is audio though, I definitely would not want the whole thing loaded at once.
You don't seem to be able to unload individual loaded assets in AssetBundles, so having a good understanding of how they work seems important
The documentation also says that if you unload the assets in the assetbundle you can't use it again till reloading the whole bundle which is a rather... spicy choice
If I wanted a databank of dialogue voice clips in an asset bundle, I'm not sure what the expected way to handle that would be in regards to not loading all the audio at once
yes, in this case all Sprites and AudioClips would be loaded because they're dependencies of the SO. AudioClips might still have to be decompressed as they play if you have that option enabled
so what would be the expected way to handle it?
option 1) carefully avoid creating a dependency graph like that
option 2) lazy way: Resources.Load
option 3) addressables and use indirect references which won't cause those assets to be loaded automatically (ex: AssetReferenceSprite, AssetReferenceT)
wouldn't option 3 wind up making individual bundles?
also I don't necessarily have access to Resources
so that's off the table
so am I like expected to make individual bundles per sound file or something?
? no, put them all in the group and make sure the group is one bundle
let's assume this is localization, and this is the Spanish asset bundle, and it has the audio clips for the spanish track in it, but I wouldn't want to load all of it into memory at once
so there's not really a great way to group them into smaller bundles and stuff
like I'd want to pull one audio clip out, play it, and when the level changes, unload all the audio that was pulled out
addressables seem rather overkill for my use case
or should be overkill rather, no idea why I can't just unload one file instead of invalidating the entire bundle
well you only invalidate it if you use the non-destructive unload. What's wrong with loading as needed + relying on Resources.UnloadUnusedAssets to manage ref counts? that should free memory iirc
does Resources.UnloadUnusedAssets affect asset bundles?
https://docs.unity3d.com/ScriptReference/AssetBundle.Unload.html also I was looking at unload and it says In either case you won't be able to load any more objects from this bundle unless it is reloaded.
or am I misinterpreting that?
the reason I'm interpreting it that was is because it says After calling UnloadAsync on an AssetBundle, you cannot load any more objects from that bundle and other operations on the bundle will throw InvalidOperationException.
which admittedly mentions UnloadAsync in Unload for some reason
and lists it twice
so the documentation is pretty wierd
if you can just call Unload on it and then Load after it without InvalidOperationException, that would be fine
I haven't gotten around to testing if that's the case
trying to get an understanding of intent before I dive into that
well if you unload a bundle, you won't be able to load objects from it until you load it again. It's setting that unloadAllLoadedObjects param to false that prevents you from loading it again
loading a bundle != loading all objects into memory btw, maybe that's your mistake. It loads a catalog of data
yeah I was asking about that. It's not loaded till I load the asset right?
right
and I can't unload individual assets right?
and then the asset is reference counted and follows the normal refcount rules
not specific ones, no
wait, the loaded asset gets unloaded if there's no references?
because that would be fine
I kinda got the impression that once you load the asset, the bundle itself had a reference internally to it (because of what it does with Unload(true)) so it wouldn't free up when I stopped using it
well you could test that theory out pretty easily. Why is Resources not an option?
because the source of the assetbundle isn't in a guaranteed location
some would be available through resources but not all of them
!collab
We do not accept job or collab posts on discord.
Please use the forums:
β’ Commercial Job Seeking
β’ Commercial Job Offering
β’ Non Commercial Collaboration
do assetbundles have a watcher or something for it to easily tell what is or isn't ready to be garbage collected?
I don't think it's actually that easy to test
btw I found this, which says you can't unload them individually, hmm
sounds like you're stuck with a bunch of bundles then
I do think I can work around it though. How fast is loading the catalog? I've never done it before
also yeah I'm making a test scene at the moment
wow yeah
that ain't anything
that's with 1GB of audio in small files too
thanks a lot for the help evil
I think I got a good idea of what to do now
did one more test, thought it was funny enough to post
load and unload doesn't seem to care too much about how much is actually loaded
the above was with Unload(false), the below with Unload(true)
how to resolve this there's little to not info on the internet about this
TypeLoadException: VTable setup of type unity.SemanticKernel.Connectors.OnnxRuntimeGenAI.OnnxRuntimeGenAIChatCompletionService failed
please help , I'm referencing an external dll which cause this issue
we cannot help you with this, I suggest you contact the developers of the dll
Debug.Log(lol.GetType());````
it returns
```System.RuntimeType```
TypeLoadException: Could not load type 'unity.SemanticKernel.Connectors.OnnxRuntimeGenAI.OnnxRuntimeGenAIChatCompletionService[]' from assembly ''.
what are you trying to do? Create an array of OnnxRuntimeGenAIChatCompletionService
I think something like this
https://learn.microsoft.com/en-us/dotnet/framework/app-domains/how-to-load-assemblies-into-an-application-domain
unity message has [] at the end.. just randomly thought it's an array for some reason lol I've no idea what I'm doing
Hello does ECS supports prefab animations? Like can I create Prefab in Entity and it will be animated in the same was as GameObject ?
That is not making an array it is making a Type for an array. I suspect you want
Array lol = Array.CreateInstance(typeof(OnnxRuntimeGenAIChatCompletionService), arrayLength);
is obj[] lol allowed
yes but why, you already have a defined type for the array
I'm off for the day tomorrow gotta check how to load the assembly dynamically at runtime and see if ot could be referenced
Dynamic assembly loading is easy. A dll can be loaded as a byte array and a byte array can be converted into an assembly
I never seen something like this error ever before
It does not surprise me if you are trying to use lol for anything
it's in your code 'object lol' is really Type lol
shouldn't be casting of type (object)?
of course not, what do you think MakeArrayType() does?
No idea but a method that returns an array of something
then wtf are you using it?
this is code advanced you are supossed to at least know what you are doing

typeof(OnnxRuntimeGenAIChatCompletionService).MakeArrayType();
returns a Type
and that type will be
OnnxRuntimeGenAIChatCompletionService[]
Anyone ever seen this? I have a user with textures that are oddly broken - no idea how to repro or test this. No error messages, just.. broken textures on two UGUI items that I'm using some shaders on. Screenshots of his texture and the expected textures (which I see in editor and my Google Pixel)
One idea is figure out which device they have and try to test on that device.
I understand this may be quite logistically difficult
Yeah, logistics aside though.. I'm not quite sure where to go from here to test.. Maybe it's something related to some shader on that device that's not supported?
I have this massive .shader file but I don't really know how to debug this.. this is HLSL or whatever?
I guess it's a bug with this library's shader.. I suppose I'll dig around his asset page and see if there's any infrastructure for reporting/fixing bugs, this is certainly above my head.. I'll see if anyone in #archived-shaders has some ideas on how to proceed/debug this
i need some people's advice on how to sync my scriptable object to scene objects. so my SO is a graph, i add to it and in the scene i have a graph manager that spawns in gameobjects for the nodes in the graph etc.
the problem comes with deleting the nodes. if i delete the node gameobject in the hierarchy the "on destroy" is called which calls the graph manager so it purges the graph of said node thats fine, but the issue is when i change scene/close the app the "on destroy" is also triggered, so this causes all the nodes to be removed from the graph, then OnAfterSerialize is called because the scene is closing so all the graph data is now gone (and saved an empty graph!). so how do you keep the gameobject in sync with the graph such that if you delete a node game object it will purge it from the scriptable object data and vice versa
dont use on destroy
or this
https://discussions.unity.com/t/application-quit-and-ondestroy/114517/2
if i dont use on destroy how else do you clean up the graph data if i delete the gameobject representation
wait why your graph manager requires gameobject to inform it? if the vertex get removed it should update the graph immediately
the graph manager is the one that links game objects to vertices from the graph object
if i delete the game object it needs to report that so graph manager can remove the vertex
same goes if i delete the vertex from editor it needs to destroy the game object
the manager is the inbetween link
so your graph manager knows the vertex got removed and it can sync the data in disk, no need to use on destroy
no, if i delete a node game object it doesn't know unless i report to the graph manager first
it just feels a bit flimsy the way its all setup
how you remove the gameobject?
delete it from hierarchy in editor
you can just use the way in the link to distinguish real removal and application quit
i am not familiar with editor scripting
Your scene loading has to suspend the ondestroy handler in the SO or manager. There is no magical builtin way to do stuff that the engine was not designed to do.
kinda wish unity had more messages to distinguish these differences
That would complicate stuff for 99% of the people who donβt need them and drag down performance
could pass an enum in the argument which states the origin of the call then
thats what i often do in custom editors already to distinguish certain types of edits or deletes
whos got a movement system script in unity 3d they can give me pls??
#π»βcode-beginner, and you can surely find the basic movement scripts in the web
oh okay ty
Are you using Addressable ? Usually, I have similar issue when addressable is set to the wrong platform. (Using Switch addressable on PC by example)
I had exactly same effect on some UI objects one of which was using geometry shader and it was simply weird looking Z-fight
If I have a scriptableobject which has many List<ScriptableObject> fields, and I instantiate that. Are the list members also copied, or will they be set to the same instance?
(i.e. is it a deep or shallow copy)
Object references are shallow copies
yes in general, but for unity objects its a bit more complicated I think
I think they do deep copies of everything thats serializable, except for things that are derived from UnityEngine.Object?
but not sure If I understood correctly
I'm not using addressables in this project.. I emailed the author and they asked me to update the library and try some toggles in the shader, so we'll see if that's the issue.. just don't know enough about shaders to know what the root cause might be (ie, bugs on one platform but not another)
Hi! Not sure if this is really and advanced concept, but I'd really appreciate some help on a concept I want to try out. I'd like to make a bunch of "rooms" for let's say a 3d game of irrelevant genre. I would like to have it so that the next room a player enters is "procedurally generated" in the sense that a script would have a bunch of prebuilt, pre generated rooms at its disposal and pick one of the rooms and plop it at connecting points so that everything connects nice and tidly. I don't however know how to start, or how to provide this script with this set of pre-generated rooms. Maybe I just haven't done my research but I don't know how to describe this concept aptly enough to find any info online.
Any help is appreciated. Cheers!
Any maze or dungeon generation algorithm will do this
That was a stupid question. Thanks for the help though
That's what I mean by object references, UnityEngine.Object references. Serializable classes/structs are serialized by value.
Help with ScriptableObjects. How do you use them for multiple objects, RTS units for example. Just for one type of unit, should you make multiple instances of one SO to use unit stats on multiple number of this unit? Why can't you just use local variables in prefabs without SO? Perhaps i don't understand how to use them correctly
Yeah, you create instances of your SO, and then add them to your units. This is helpful if you are using each SO in multiple places - and trust me, you do end up with some duplication eventually.
But I guess nothing's stopping you from just storing the default stats in the prefabs, it's just that it might become a bit annoying later on
I didn't see in any of guides of using SO for spawning or just making new instances in runtime. Is CreateInstance() in runtime ok?
wait, I think there's a misunderstanding. Why do you want to create SOs during runtime?
For spawning new units
You need to have individual stats for units
nonono, you're misunderstanding the purpose of SOs then
You should store things that don't change (like base max hp, max energy or base movement speed) in an SO, and store changing things (current hp, current energy, amount of speed upgrades) in local data on the gameobject
Ah
and just link the SO to the gameobject in a script as a variable, and use the unchangeable values from the SO when you need to, for example, set hp to max, or something
Ok, i get it, appreciate it
You can see SO as the concept of the object. By example, if you want to buy a fish, the concept of the fish (everything that is share between fish) should be store in the SO. The name, the description, the price, the average value, etc. The rest should be in a seperate structure. Things like the actual weight of the fish, the time since it has been capture, etc.
Hello I am developing a game and I generate the level and the player at runtime, the enemies spawn from different places, but I want to make the enemies AI to not get stuck on obstocales between them and the player, but I am having issues with navmesh do to generating the prefabs player and enemies at run time, how can I proceed in this, I have seen different videos but didnt quaite made it work.
So I'm taking the advice I was given to make an ICastable interface for all my spells, I'm just not sure where exactly to implement this all properly, so I think my whole structure needs a bit of a retool to get things flowing right. Currently everything works as expected the way it is, now I'm just trying to break it up so the SpellManager has a bit less to do. Here's the breakdown as simply as I can put it without dumping tons of code here:
my Player class searches for the SpellManager spellManager on awake, and used it for things like checking spellManager.IsConcentrating (player cant move if a spell makes them concentrate on it), or activating spellManager.CastPressed()/.CastHeld()/.CastReleased() when it detects the proper gameInput. The SpellManager currently handles the casting from there
my spells are currently made of a few parts. there's an Abstract Scriptable Object class called SpellData, that holds the absolute basics like a spellName, mpCost, whether it requiresConcentration, etc. that's inherited into the Scriptable Object classes like ProjectileSpellData and BarrierSpellData, which holds spell specifics like its projectileSpeed or barrierDuration, things like that.
The SpellManager class essentially holds a dictionary of SpellData scriptable objects called the spellMap (a whole different topic on how im handling spell switching another time), and a reference to the SpellData currentSpellData. then when it gets a CastPressed() or CastHeld() etc from the player, it checks if (currentSpellData is ProjectileSpellData projectileSpell) or if (currentSpellData is BarrierSpellData barrierSpell), starts a TryToCast() method that checks the players mp and cooldown to see if they can cast it, and does the relevant action like FireProjectile() or CreateBarrier()
My current idea is to make a new class for each spell type, so like ProjectileSpell class and BarrierSpell class that both inherit from an ICastable interface that gives the CastPressed() CastHeld() and CastReleased() methods, then having the spell manager call those, but other than the concept of it I'm kind of confused on how to move everything around
Move what around ?
@versed wave Please don't crosspost
what does that mean?
Posting your question across multiple channels.pick one.
Im sorry, I tried to lay out my issue and intention in that post, so I dont know how to answer other than what I already said.
I have some casting methods in a SpellManager that act differently depending on what kind of SpellData scriptable object its being given for parameters at that moment, by checking if that SpellData inherits into ProjectileSpellData, BarrierSpellData, and others. I'm trying to use an ICastable interface to make the SpellManager's part of it easier and cleaner for future things I want to work on by moving those into their own new classes.
Right now I just make a ProjectileSpellData scriptable object, set its name and any parameters it needs, and I pop that directly into the SpellManager's list. If im going to be switching to classes with their own ICastable implementation, then Im just confused on some of the fine details
No idea what is your issue. Why can't you just do something like:
public abstract class Spell
{
public abstract void Cast(CastContext context);
}
If you want to serialize data, you can do:
public class FireballDefinition : SpellDefinition
{
public class Fireball : Spell
{
public override void Cast(CastContext context);
}
[SerializeField] private float damage;
public void Spell Cast(CastContext context)
{
FireBall spell = new Fireball();
spell.Cast(context);
return spell;
}
}
ICastable is not necessary as long as you can only cast spell.
If you ever find yourself in need to cast something else (maybe interaction ?), then, only then, you should create an interface. At the moment, I believe it is better to work with a type.
Obviously, it varies from people to people, but from experience a lot of people dislike dealing with interface that are not useful if they are not the one that created it.
Hence, I suggest that you incorporate interface only when needed.
I agree with ICastable can just be the object itself if you only have the Cast method exposed publicly. What I like to do is have interfaces like ICaster on the entity which casts abilities and also include other objects which may modify those abilities, but may not directly be included on the ability object itself.
So, if an entity is an ICaster we would know it has mana, it can cast abilities, it has stat related to casting those abilities, and it may have some other utility classes that may modify those casting abilities further.
is it possible to check in the fmod api if the event is valid?
Can I use Compute shader to define a buffer for DrawMeshInstancedIndirect grass each frame(for frustum culling, LOD and render distance)?
A compute shader can write to a buffer which you create from script.
Has anybody worked with behaviour trees before? I know there are many different libraries available, but in general, how can I have two leaf/action nodes running in parallel? I want to chase my character and play an animation. The ChaseCharacter-Action has status Running while chasing, how can I also play an animation (probably also Running or returning True)? Any idea?
Hello folks, I'm gonna hang myself at dawn because of this ongoing bug. Take a look into the code and save a soul!
private async Task<string> CheckAuthorizationForTheContent(string[] folders, string fileName)
{
string accessURL = /* DataManager.Instance.GetAccessURL();*/
"https://webapp-240504440.azurewebsites.net/Storage/GetDownloadLink?token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtcHg1Z2M3NGt5bmxrMTVhMy51cy5hdXRoMC5jb20vIn0..010qduiKQfLipG2R.g3C3KemJbM3j8CGMvyvbugKNgRkLswCpPOQSGF9Lkm32cFBAEAkV4-MFsQCkAwHoieZ1zhvl-r0ymxqnbiRdROc-3FfhABfsogMNnFqYcrp3eQcJrfmavxadsfadsfasdfasdfuc2bkVCSoK7-2NNlhQ9zS6Ug89xv9-U-VsmJ7UJRoHj6nbsarMqh8bQB0uyn9G5q8FWjdtMMdv0TQp7yergJnhav7WGMcXC2Vm7vFlZHJneAXQRkRazi4D3FfqhL6AOLs68rygg2Kt2C8HaQ8Nb1WKBktPsjRvCA5JJt9BGZXOjUughWG2eD96Zb325OYOSDkamlfe9cUfzKwfnHKAYLOb4UDG42ZORiLkkBMN7kFPG3rgbGdQhaGn9tJp8FI.i5tYUDFtCqHlD_KTDzvBLQ&blobName=98765bb52c99b2067895e7c3_TheOne%2FStandaloneWindows64%2F00e5d021-0f3a-4ea2-ae20-6db84de3d09b_ramenroyale_08a897ae57b2fb969aa6fe0e178d6b70&bucketName=mealar_production";
UtilityClass.ParseURL(accessURL, out string baseUrl, out string token, out string blopName, out string bucketName);
string url = UtilityClass.URL_SCHEMA;
url = string.Format(url, baseUrl, token, MoveThroughParamsDirectory(folders, fileName), bucketName);
using (UnityWebRequest www = UnityWebRequest.Get(url))
{
await www.SendWebRequest();
if (www.result == UnityWebRequest.Result.ConnectionError)
{
return null;
}
firstTime = false;
string responseText = www.downloadHandler.text;
return responseText;
}
}```
This goddamn code freezes unity after the second request.
I'm going crazy!!! There is absolutely none clue, none problem appear!
Am I missing something here? Thanks
I don't know if that token in the URL is sensitive or not, but it seems to be a JWT so my guess is yes and you should probably edit the message and also revoke that token.
thanks for the input! It's not a real token.
Does Unity releases the memory used by NativeArray to system memory, or the memory will remain available for the process as the Mono managed memory does?
Remain for the process
Does it freeze on the await?
Perhaps implement a timeout? Still weird that a second request would freeze the application though
I did it. timeout gets never hit
So it's before the await?
sorry sorry. just I'm confused. yes I put timer and timer never works. the whole app freezes and I have to use task manager to get rid of the corpse of unity
I think it's a good idea to figure out what line specifically freezes though
If it's the await itself in this code or before it even
await line %100
Would it be possible that you try the HttpClient class for this?
See if that freezes
when I remove await and use it syncron then it works but since it has never catch the promise the returnung value becomes null
I'll try it out! thx
The code seems totally valid so perhaps this is some issue with the current client you use
There's no reason for it to lock up
are you using unity 2023? just wondering if this is using unity's own awaitable for UWR or something else
not that i know of, just wondering if it was a 3rd party library since a few of those existed before it was officially supported to await those
I see.
if the unity main thread freezes it's often still possible to pause it in the debugger if the problem is an infinite loop in C# code somewhere, it's probably worth trying that
if you're lucky you can even sometimes attach the debugger after it's frozen haha
no when it comes to await, the unity freezes and debugger just does nothing
not sure there is nothing like might cause to infinite loop
make sure to break all so you can actually inspect what is happening on the main thread
I'll give it a try asap. Thanks folks. I'll get you updated and get more help in the channel if I'm going to crazy
I have a dynamic weather system in URP. How do I interpolate smoothly between the different Reflection Probe?
It seems to just not be an existing feature anywhere, bar rebuilding a new cubemap yourself every frame, which is hella slow.
How would that work? Isn't reflection probes just baked images much like baking light maps? Also try #archived-urp
Anyone here a mobile game developer
#π±βmobile ... after reading https://dontasktoask.com/
Hey, so I am working on a custom logger. This logs out when I get a log from a script.
I am having issues figuring out how to get unity to select the correct log location, when double clicking in the console, instead of where the custom logger is.
If any knows of a solution I can use I have been scratching my head on this one. Thx.
sure, you can get a reference to the stack trace object and then use the last but 1 location as the log object
Cool could you give me an example of how I could do this?
Awesome thx I will check this out.
Does anyone have some tips for using git lfs successfully with unity? I'm constantly getting shit breaking when unity tries to do something to files at the same time as git lfs during "rehydration" of the pointer files...
and it's.. giving me heartburn because I can't tell easily if unity is going to break something accidentally
you dont exclude the libraray folder in .gitignore?
i do
TBH i'm not even sure why those file in use conflicts are happening.. I just got git lfs online today so I was assuming it was that
hmmm.. antivirus perhaps? nah.. that would be an odd coincidence... for it to start right after that
no antivirus, i live on the edge π΄ββ οΈ
but actually - maybe my backup software is trying to do shit in there.. i'll check that
yep.
π€¦ββοΈ
thx sir. :p
hehe, that was ALL you bud π
nah, I needed someone to think outside the unity box.. antivirus led me to the right answer
what a wild 24 hours though.. i had to .. sort of urgently integrate firebase, and they have 2 very large files in the package and it just horribly broke my branch, and fixing it was a nightmare
https://github.com/firebase/quickstart-unity/issues/547
"since there haven't been any recent updates I'm going to close this issue"
this is such a frustrating gotcha with this particular package (if you're using github)
not familar with firebase.. but I didn't think packages, in general, got included in the git repo.. am I mistaken?
if they can be resolved from the packages.json or whatever - but the firebase package isn't in the unity registry so you have to install it as a "custom package" and it has to ride along in the repo if you want your CI/CD pipeline to be able to compile it
ah! so the code goes in the asset folder directly? I see
bits and pieces go everywhere tbh
and these guys... these are the naughty ones
Aight, ran into an issue where both the GetAction() and the GetTempAction() returns null. I might have overlooked something really simple, but haven't been able to find the issue, but here's the code:
https://hatebin.com/qhialwdtky
The tester.cs
InputManager.GetInstance().OnLoad += InputManager_OnLoad;
private void InputManager_OnLoad(object sender, InputManager.OnLoadEventArgs e)
{
inputItem = e.instance.GetTempAction("SpawnItem", "<KeyBoard>/space");
}
private void Update()
{
if (inputItem.GetTriggered()) //Line 38
{
firstConveyor.TrySetWorldItem(new WorldItem(item, new Vector2Int(1, 3)));
}
}
post Tester.cs
it's hard to tell what your intent is.. have you stepped through it with the debugger?
{
inputItem = e.instance.GetTempAction("SpawnItem", "<KeyBoard>/space");
}``` The, ``e.instance``, seems odd to me. is ``e`` NOT the instance itself? Is this a unity class? ( can't find docs for it)
https://hatebin.com/qhialwdtky
line 191, defines the OnLoadEventArgs
and on line 224 it just passes it in instance.OnLoad.Invoke(instance, new OnLoadEventArgs() { instance = instance });
reading...
You mean the vs 2022 debugger?
k - couple things, just from a layout/organization perspective..
You're subscribing to an event of onload from a singleton but not unsubbing - best pattern here would be to do this in enable/disable.
You're getting an action from the instance - but why? why not just let the input manager manage the input and then have things around your game listen for those events?
yes, visual studio debugger - if you don't know how to use it .. well, you should, especially for questions in this channel π someone in gen/beginner can help w/ that
i'd restructure your input manager to fire events and then let.. whatever needs to listen to them subscribe to those.. pseudocode:
I know how to use it kinda, but it doesn't flag anything when i ran it on this, which probably means im using it wrong but idk-
public class InputManager
{
public static event Action InputEvent<string>; // string action
}
public class Tester
{
private void OnEnable() => InputManager.InputEvent += OnInputEvent;
private void OnDisable() => InputManager.InputEvent -= OnInputEvent;
private void OnInputEvent(string action)
{
if (action == "jump") DoABarrelRoll();
}
}
the big advantage is: it lets you step through each line of code, and lets you look at all the in-scope variables, and see what values they contain.
you don't need to be passing around references to the instance.. that's kinda the whole point of a singleton.. that it just exists at the "global" level
{
inputItem = InputManager.GetInstance().GetTempAction("SpawnItem", "<KeyBoard>/space");
}``` <- sanity check , access singleton directly
it's also just a lot simpler to read and understand.. what you have currently is kind of a mess of chasing around pointers to an instance and.. unsurprisingly, it's hard to figure out what's broken or where your NRE is coming from since the mental workload of this is high (and not necessary)
your tester (and I imagine the rest of your game) also has/have a lot of entanglement with the input manager.. like.. needing to know when it's loaded, listening for a certain action in update, etc.. your "consumers" of input should generally be able to do so with a minimum of fuss - just one line to listen to an input event and one line to stop listening (OnEnable/OnDisable above)
since you also have race conditions of whether or not the Tester is Started before the InputManager fires OnLoad - in which case your Tester.InputManager_OnLoad() method will never get called, or will get called randomly sometimes and not other times
(which is probably your issue here, btw)
InputManager.OnLoad fires - but Tester doesn't exist yet.. then Tester gets started and subscribes to input manager's OnLoad but it never "hears" it because it didn't exist when input manager fired it
so inputItem on line 38 is null
here's a couple screenshots that might help - this is my idiomatic use of singletons and rendering components that need to listen to events
I'll look more into doing it the way you described, but how'd that work with unitys new inputsystem? Wouldn't that require for the "consumer" add in one OnInputEvent function per action they want to listen to? if you did it like that with the string action thingie, wouldnt that make me need to loop over all the actions inside the InputManager each frame and send a event to it? Like I dont see how I could do that since the inputAction.ReadValue<T>() needs to return the value of the action, not just if it happened, due its used in movement where a vector2 is returned, but maybe im just not that used to working with singletons and cant see the path
put an update loop in your input manager to listen for all inputs
and just emit an event with whatever the action/binding is, or whatever you care about
I haven't used it extensively since I make mobile games, but .. that's how I'd do it.. your input manager would just listen to all inputs and then emit the string action that you care about
and also, yes, essentially one "consumer" for whatever it needs to listen to but that's just one way to do it, depends on the game
like if you're a platformer game and you want your player to respond to a bunch of actions like "run right" or "jump" then your player object would just listen to those actions and respond accordingly.. that might not be a great architecture, but it's just one way of doing it
for a platformer, another architecture might be to couple input manager and something like "player manager" more closely, so the player manager listens to the input manager for all the inputs, but then emits its own events for rendering components.. like "takes damage" or "starts slide" or "dies" or something
then you could have something like a particle effect renderer that flies around near your player and changes emission rate or color or even turns itself on/off by just listening to PlayerManager.HealthChanged events
then your player manager doesn't need to know anything about the way the world is rendered.. it's just emits the events based on what happens in gameplay
dunno if that makes sense
that makes alot of sense actually, the part i cant really get is how id emit the Data easily without the OnLoad that Gets all the acitons
OnLoad is called once at randomly (when the gameobject for it loads), not when the actuall object is created and setup correctly, so gathering the Inputs later inside the update loop would work just fine with InputManager.GetInstance().GetTempAction("yada", "yada");
I didn't have this problem before I added that the InputItems get stored inside an dictionary, so that I don't create multiple items for one binding
why i added a OnLoad is because before i had the problem that the InputManager class didn't load before the others, but now i might have ran into the exact opposite problem..
Is something like
public void OnInputEvent<T>(string name, T _value)
be possible? Would the "consumer" be able to only subscribe for only float inputs? (The actions themselfes does not store which type they are so i'd still need to send ALL of the Actions and values into it, and then if the name would match i could move on.)
Found the issue..... It's so simple,
inputActions = new Dictionary<string, InputItem>();
tempInputActions = new Dictionary<string, InputItem>();
forgot to initialize the Dictionaries...
how can I tell the compiler to chill out and just trust me on this one
like first of all AIController<T> should be able to cast to T considering T is constrained to a type that it already is
secondly im checking if its of type T
and third just like let me do it anyway then throw a runtime error if it doesn't work
(because it will work)
I think i got it?
T obj = this as T;
if(m is T) {
currentState.stay((T)m);
}```
oh ok
weird
ty!
whats the difference between (T) and as T
that makes that work
because as T tries to cast and will return null if it fails
Don't forget you can also do:
if (m is T cast) {
currentState.stay(cast);
}
not a syntax I've ever used, what happens if the cast fails?
of, silly me, it cannoy fail
It's the same thing as (T)m yeah
scope limited so could be useful
Hello I am developing a game and I generate the level and the player at runtime, the enemies spawn from different places, but I want to make the enemies AI not get stuck on obstacles between them and the player, but I am having issues with navmesh due to generating the prefabs player and enemies at run time, how can I proceed in this, I have seen different videos but didnt quite make it work.
Regenerate the navmesh at runtime.
You can also invert it by doing:
if (m is not T t)
return;
// use t here
Which this code should really be making use of guard clauses, instead of 3 levels of nesting.
And depends on if currentState/currentState.stay is Unity objects or not, you can use optional chaining and clean up all the null checks.
public class PrefabScript : MonoBehaviour
{
private NavMeshSurface nav;
// Start is called before the first frame update
void Start()
{
nav = GetComponent<NavMeshSurface>();
nav.BuildNavMesh();
}
}
I already do
Then what's the problem?
thats what Im trying to figure out, the nav mesh isnt being built
even though the prefabs have navmeshsurface and I build the navmesh on Start
its my first time working with it and I cant seem to figure this out
Are you sure the objects exist in the scene when you build it?
yes 100%, they are generated on runtime and the entire level are those objects, so no objects no level
screenshot the inspector of the NavMeshSurface
which are you using btw, GitHub NavMeshComponents or com.unity.ai.navigation?
com.unity.ai.navigation
oh even better
So you are collecting all objects from difference layers using their meshes. I notice your floor has no mesh so it wont be included
guards are like if(!condition) return right
what do you mean it has no mesh?
I see no mesh here
Correct.
if you clear the NavMeshData and run your script, does it come back?
are you sure your script is running?
coz I dont see prefabscript on the inspector either
yes it is running
I printed inside it and its printing, and on my screenshot is the generated nav which is that shape I dont know why
must be your mesh, change the collection to collider
I did and its the same result
its assigning the navmeshdata btw
looks like you are generating lots of prefabs.
what I would do is have an empty gameobect with the Navmeshsurface on it. Instantiate the floor prefabs as children of that and then build the navmesh when all done
okay I'll try it thanks
@upbeat path I did, however I dont see any navmesh
How should I proceed?
Any advice on developer experience for handling secrets while developing a game server in the Unity editor?
Iβm using third party services (AWS gamelift, twilio) and want to populate secret values in my Unity editor while iterating the game server code. In production, the game server obtains these secrets from either command line arguments or environment variables.
While developing in the Unity editor a monobehaviour have serializable props that can be set. This stinks because someone can accidentally version control secret values. Any advice on how to make this better?
show your script now
it may sound silly but, PlayerPrefs
Go on?
save them there, they are in your registry and cannot escape
what Script?
PrefabScript, the one used to create the NavMesh
public class PrefabScript : MonoBehaviour
{
private NavMeshSurface nav;
// Start is called before the first frame update
void Start()
{
nav = GetComponent<NavMeshSurface>();
nav.BuildNavMesh();
}
}
βDo not use PlayerPrefs data to store sensitive data.β
https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
Even though it says that, maybe itβs fine since weβd just be using it for these secrets while developing.
Is there a UI so I can set playerprefs in the Unity editor? Or would I have to build something?
right so you did not change it to run AFTER you instantiate the floor prefabs. It also needs to be on the empty gameobject
At runtime, it's fine just on your own machine
right
you would need to make a little script to store them, run it one then throw it away
Wait⦠Playerprefs only works at runtime?
Does that mean the devx would be to press play and then add secrets? Or can I set them and access them from the Unity editor context
I changed it now its building this navmesh
PlayerPrefs are for runtime EditorPrefs are for in the editor
and you set collection to colliders?
Iβm not sure I understand your suggestion then.
Can you talk about it more so I have a clearer picture on how to implement what youβre suggesting?
most odd. which Unity and AI.Navigation versions?
it's simple really.
you set up some PlayerPrefs much like you would environment variables.
make a script that initially sets the values then once it has run you can throw it away because the values will persist.
then you can just access those values when you are testing your game
Where are the values stored before they get into PlayerPrefs?
Unity- 20210.3.20f1 AI.Navigation - 1.0.0-exp.4
IN A SCRIPT WHICH YOU CAN THROW AWAY AFTER IT HAS RUN
IN A SCRIPT WHICH YOU CAN THROW AWAY AFTER IT HAS RUN
π€
Whatever dude.
I had already said that, twice
if you have another method of setting them outside the editor, i'd go for EditorPrefs personally, but either way this is probably a nice thing to make a little custom editor window if others in the team will be using it
Sounds like it.
no, the point is that it cannot be exposed
you do not want to be serializing the values in Unity
Is there anything wrong with using environment variables for this? The only annoying thing is that you need to restart Unity (and Unity Hub) after changing variables for Unity to pick them up.
Thanks for considering my question. Nothing wrong with the solution and something we've considered. The developer experience (devx) is just a little awkward and time consuming.
- New envvar needs to be set
- Close unity editor, if open
- Set new envvars (source into current shell session if need be)
- Craft command line args to open unity editor, prepending ENVVARs before unity editor (time consuming)
- Unity editor now knows what the latest ENVVAR values are for what my game server uses.
It is time consuming enough to break someone out of their flow, given how long it takes unity to close and then reopen.
Most designers would rather stay out of the command line, if you know what I mean π
you know you could just keep a text or json file in persistentdataPath, that will keep it well away from Git
A variation of this is something I'm entertaining. Solution: write a script that looks for .env in the project (AssetDB) to set the envvars. It monitors the file for changes and resets the envvars.
- Add
.envto.gitignore - Add file, set secrets (or share the file)
- When anything changes (aws gamelift fleetid is the thing changing the most), just edit that file
- Monitoring editor script sets the envvar for the unity editor session (stored in app's memory, not in anything serialized)
until someone blits their git ignore then you are screwed
If you like the experience of serialized fields, but dislike the possibility of it getting tracked by VC, you can create a custom editor that uses PlayerPrefs/EditorPrefs/temp file to save and load the secrets instead of serializing it in the project.
Acceptable risk for the much more improved devx
I would value security over experience any day
Sounds like you have difference tradeoff tolerances than I do; makes sense since we have different perspectives. It's all tradeoff designing in the end.
I mean if you are going to go the gitignore route, why not just hard code the values into a sript in the project and ignore that
you are right, I am paranoid about the security of my servers and rightly so
Code scares designers more than config files like .env, if that makes any sense. I like @sage radish 's solution a bit more.
If you like the experience of serialized fields, but dislike the possibility of it getting tracked by VC, you can create a custom editor that uses PlayerPrefs/EditorPrefs/temp file to save and load the secrets instead of serializing it in the project.
Staying in unity editor is a better devx
You should be and I'm glad you are. The security of production and internal servers are of upmost importance.
That's not a bad solution, best of both worlds, can't think of a downside offhand
I just updated my editor to 2022.3.27f1 and am now using AI Navigation 1.1.5 but the outcome is the same
Im out of ideas, I use exactly the same versions as you with this setup and it works perfectly
can you go over the steps to adding the navmeshSurface very generally? just to see if I missed anything
wait one I'll just pull a project up so I can screenshot for you
thank you!
Agree. Just so I have it all spelled out explicitly -- Solution:
- Create/Update new editor tool (editor window probably) to allow game devs/designers to set secret values (from gamelift/twilio). Since these secret values are not stored in a serializable field, no risk of accidental secret leaking.
- Upon secret value entry completed the editor tool will write the value an envvar so as to not have to write handling code. Option to persist in editorprefs to avoid re-entering secret values on unity start up.
- On unity editor player run the scripts will read from envvar in appropriate
Awake/StartMB methods.
@sage radish anything else to add?
public void MakeWalkways()
{
for (int x = 0; x < 5; x++)
for (int y = 0; y < 5; y++)
for (int z = 0; z < 5; z++)
{
if (Data.shape[x, y, z] == 0) continue;
Vector3 pos = new Vector3(x - 2f, y - 2.5f, z - 2f);
GameObject go = Instantiate(quad, pos, quad.transform.rotation, walkways);
}
surface.BuildNavMesh();
agent = Instantiate(npc, npc.transform.position, Quaternion.identity);
//agent.SetDestination(Vector3.zero);
}
The Surface is on the Walkways game object
The colliders are on the Plane (2) gameobjects
Do you ever see a scenario where a designer won't check the "persist" checkbox? I hadn't considered making it optional. Do you see that as a security measure?
Do you ever see a scenario where a designer won't check the "persist" checkbox?
I think a designer would expect to enter in secret values once and then be able to use the same secret values until they enter new ones, even when closing and reopening the unity editor.
I hadn't considered making it optional.
I just meant the MVP of the editor tool doesn't need to have the feature of persisting between unity editor restarts. Though it's actually very important to have that feature.
Do you see that as a security measure?
Need to read more about editor prefs to know for sure. I would may be concerned if by setting editor prefs, all unity projects could read the values. In that case we may consider other persistence mechanisms (like writing to a gitignored file).
Yeah, editor prefs can be read by ALL projects. PlayerPrefs only by the one project
Another thought, as you are using AWS already could you not use a S3 bucket as a password manager and that way the devs don't have to do anything
What I got from experimenting is that my prefab on its normal scale doesnt show the nav, but bigger it shows a nav mesh that doesnt extend to the full mesh, how can I fix this?
make the radius of your agent smaller
the normal size still doesnt show up, I dont understand
because it will always leave an edge the width of the radius of the agent
So what can I do? Upscale everything?
I'm not sure what you are trying to achieve
I want the small size cube to have a navmesh
ok, for very small meshes, look at my surface, see how I changed the Tile size and the Region area. Im my mesh the walkable area is only 0.2 units wide
I got it
perfect
thanks for everything
np, glad we got there
you might want to change the agent step and jump height if you dont want him walking on top of the walls
void OnDestroy() {
if (loadout != null) loadout.OnSetHitEffectsChanged -= OnSetHitEffectsChanged;
if (controller != null) controller.cust.OnPrimaryLoadoutIndexChanged -= UpdateUsage;
if (controller != null) controller.cust.OnSecondaryLoadoutIndexChanged -= UpdateUsage;
addEffectButton.onValueChanged.RemoveAllListeners();
buttPrim.onClick.RemoveAllListeners();
buttSecnd.onClick.RemoveAllListeners();
}
guys I've been doing clean up like this with everything, is this redundant? do I get memory leak if I dont?
this is good and correct
and very tedious
thankyou tho
It would be nice to have some way to automate that
My reactivity system does that, and it's quite trivial to do any kind of "automatically clean up all the listeners"
This goes back to that reactivity system is essentially just a thin abstraction on top of the basic event handler, except every event subscription goes through Signal.Subscribe so you essentially have a central place to hook into event subscriptions.
The implementation is extremely simple: you have a global variable as the current context, where it's just a list of unsubscribe actions:
abstract class MyMonoBehavior : MonoBehavior
{
private List<Action> _unsubscribes = new();
protected abstract void Setup();
private void Start()
{
GlobalContext.Unsubscribes = _unsubscribes;
Setup();
GlobalContext.Unsubscribes = null;
}
}
Now in Signal.Subscribe, you simple check the global context and add unsubscribe to it:
GlobalContext.Unsubscribes?.Add(() => ...);
Now you can just call all the unsubscribes in OnDestroy:
private void OnDestroy()
{
foreach (var unsubscribe in unsubscribes)
{
unsubscribe();
}
}
(The actual implementation is slightly more complex but not by much, the basic idea is the same)
Boom, you now have a MB that automatically unsubscribe all the listeners when it gets destroyed:
class Foo : MyMonoBehavior
{
protected override void Setup()
{
Player.Hp.Subscribe(value => Debug.Log($"Player Hp changed to {value}"));
Player.Level.Subscribe(...);
// ...
}
}
You can subscribe to as many things as you want in Setup without having to worry about forgetting to unsubscribe a listener and causing it to keep triggering after destroyed and causing memory leaks, no need to manually keep you subscriptions and unsubscriptions always in sync during code changes and refactoring, everything is automatically cleaned up and unsubscribed for you.
A reactivity system solves so many state management problems that I feel like it's really under utilized, but I do get the reasons why that is, because it's not how most people write code. Most people write procedural code where you explicitly give step by step instructions to the computer by saying "when destroy, unsubscribe this," and if you forget you get a memory leak on your hand that is potentially difficult to even detect.
I have a problem with nav mesh builder.
At the beginning of my game, I create some buildings and then build/update nav mesh. It is OK most of the time but rarely, it cannot bake it and apply changes.
The buildings have nav mesh modifier and box collider. I use nav mesh plus package
foreach (var structureLocation in _initialStructureLocations)
{
_structureSpawner.Spawn
(
structureLocation.Definition,
structureLocation.Location.position,
isConstructed: true
);
}
await UniTask.Yield();
_navMeshBuilder.BuildNavMesh();
When spawning new buildings, it is completely OK and update nav mesh
[Button]
public void BuildNavMesh()
{
_navMeshSurface.BuildNavMesh();
}
[Button]
public void UpdateNavMesh()
{
_navMeshSurface.UpdateNavMesh(_navMeshSurface.navMeshData);
}
So it's been a busy few days, but in the meantime I've managed to redo my SpellManager much better! I took what you said and went with the abstract over the interface, a simple Spell abstract that's passing overridable CastPressed()/CastReleased(), as well as the functions all spells would share like checking mp cost and cooldowns, so they're being handled there and I don't have to worry about it in my actual Spell classes! Thanks for the advice!
Is the idea of reactivity system some general programming concept? As i search for it, there are only some vue related things comming up.
Do you mind elaborating on it a bit further or send me some other information about this, or some actual implementation, as i'm interested in the the thing you're trying to solve here. I've seen some other implementations for a more specific use case like unity events in an talk about SO for example, that kinda go a similar direction.
But i can't see how your pseudo code here would make any sense, and even if it did, why the indirection over this global thing here?
Here's a short write up I've done a while ago, it explains the basis of a reactivity system and what kind of issues it solves: #archived-code-advanced message
What I've written above is a bit of an extension of the previous write up, it makes more sense once you understand why the layer of Signal abstraction exists over just using events directly (specifically for the use case of automatic clean up, it allows a global point to hook into any event subscription)
This seems interesting, but I feel im misunderstanding something. Ik it's not a plug and play example, but wouldnt you have to create wrapper classes for everything? Like the player.Hp example, its compared to 0 but also passed as a dependency. How would this work?
You have a Signal<T> class, where the inner value is accessed via .Value. However it also has an implicit conversion operator that converts Signal<T> to T, so you can just use Hp + 10 directly.
I see, thanks
This does look like itd be cool to use if I didnt spaghetti my way through most of my system already π
Yeah I definitely would not recommend ripping out what you already have, let what works continue to work.
It's just a different style of programming (reactive vs procedural) that is specifically very good at dealing with state management, so it's worth exploring in a toy project or something.
thx
Thanks for the explanation/ linking this. I didn't quite get all of it and had to turn away from computer, but i will look into it later again. I guess i have to play this a bit more through in code or on paper to see how it will work and when it's good to use this.
I'm creating a music game where the player is moving inside a tunnel and can create twists and turns using WASD. The movement is completely free form and currently it's very basic:
- If the player presses, for example D, then transform the tunnel to the right by some constant speed.
I'm looking for advice on how to implement better movement in the game. Something that is smoother and more dynamic, it should feel really great when combined with the music. It should feel like the player is moving in sync with the music. e.g maybe at some parts of the song, the movement is really fast, and in others slower.
one thing on my mind is bezier curves, and i'll try that next, but let me know if you guys have any tips!
Place coins or a collectable in the tunnel. The player has to try to move the tunnel so that they collect the coin.
https://gdl.space/imumasaceg.cs
this is some code I copied from some smart dude, its to make a random 2d tilemap, in line 113 I attampted to make a chance to spawn an enemy on every tile, but the pos is off, I thought it was something to do with my grid size (2.5) so I made the pos multiply by 0.4, but now its more of a mess
you need to convert your grid coordinate to world space via the Tilemap or the Grid
not with magic numbers
How do you suppose (am a noob and donβt know shi)
With the functions made especially for that of course
hey guys i am trying to make a 2d game but when i implemented the wall jump the player continuously started flipping can you help me solve it
here are the code
How lenient are your timing windows?
lemme make a thread
i dont know much about cooding it would be a great help if you guys can help me
You should be in #π»βcode-beginner then!
oh oky thanks
rhytm game
I have a system design question. I'm making a survival game, the most common class is unsurprisingly Item. There will be many different types of items, probably over 50. The way I envision is that any item can be held, and the player can use and held item on any other item (usually just existing in the world). Not all items are compatible with each other, and a lot of the behavior between most items is going to follow a pattern but a lot of it will also be too unique to have a system, so I will need to hard code the results of a lot of interactions. Additionally, it's bilateral interaction, so using Item A on Item B can be different than using Item B on Item A.
I have a couple ideas on how to implement this but I want to know if anyone has a system they've seen or heard of that would work well for this purpose. Thanks!
I'd make a table of item combinations, and when you are to Combine(Item item) with another item you would look up the combination in the table.
I see. Would each combination refer to a helper function to actually execute the interaction?
One question you should answer is are these interactions symmetrical or asymmetrical?
Is using A on B the same as using B on A?
No, not the same.
I imagine they'd be different, right? Since using water on a campfire is probably different from using a campfire on a bucket of water
Yes it would be different π
Additionally, it's bilateral interaction, so using Item A on Item B can be different than using Item B on Item A.
Ok then you 'll want to make like a "key" for this interaction which you can use to look it up. Something like:
public struct InteractionKey {
public Item A;
public Item B;
// implement HashCode and Equals for this
}```
Then you can use a Dictionary to look up the specific interaction with this as a key
If they aren't the same for each combination you can still key value pair
Got it, thanks guys!
assuming you always receive an item back after combination, then you'd probably want a polymorphic Use() method to handle that
for any specific interactions for that item
The way I planned was to use items only as containers for information (i.e., tool hp, item type) and all interactions would be managed by an overhead manager script on the server.
item use rpc* -> manager script -> use
Oh oh I see
My cheeky way would be something like:
public delegate void InteractionHandler(Item a, Item b);
public static void WaterCampfireInteraction(Item a, Item b) {
WaterItem wi = (WaterItem)a;
CampfireItem campfire = (CampfireItem)b;
wi.Consume();
campfire.Extinguish();
}
Dictionary<InteractionKey, InteractionHandler> itemInteractions = new() {
{ new (ItemType.Water, ItemType.Campfire), WaterCampfireInteraction },
// ... more interactions
}```
Yeah, that seems very robust. I like it.
Alternatively:
void Combine(Item first, Item second)
{
switch ((first, second))
{
case (WaterItem a, CampfireItem b): Combine(a, b); break;
case (CampfireItem a, WaterItem b): Combine(a, b); break;
// ...
};
}
void Combine(WaterItem a, CampfireItem b) {}
void Combine(CampfireItem a, WaterItem b) {}
// ...
You can easily use multicursor in your IDE to create the switch.
It still sucks that you have to keep the two parts in sync, but pragmatically speaking that's a fine tradeoff for how low amount of effort it takes.
Oh this is also a good idea. I wonder the pros and cons of this compared to using a dictionary?
Not sure how it works for pattern matching but normal switch statements get compiled down to jump tables which are basically the same as a dict
Dictionary will scale linearly, but realistically it won't matter because you won't have thousands and millions of item types.
Yeah in this case it will have to compile to a bunch of if else.
As for the pros, the major one is that you don't have to keep writing var foo = (Foo)a; var bar = (Bar)b; in every single one of those methods.
Thank you very much, I'll go with the switch for now for readability and if it becomes to unweidly I'll switch to the dict. Thanks @sly grove as well!
https://paste.ofcode.org/JXe6SRLj9tJfTtctNMg5DF
is this a good stamina logic, if not, how do I approach it?
Does it work? π€·ββοΈ
hi yal
Those duplicated properties like this one and it makes code hard to read and hard to control the execution flow/maintain:
[SerializeField]
private bool _isWalking = false;
public bool isWalking{
get{
return _isWalking;
}
set{
_isWalking = value;
animator.SetBool("isWalking", value);
}
}
You'll need to change "IsWalking" anyways, just the the animator bool in there and keep the variable cleaner
[field: SerializeField] public bool IsWalking { get; private set; }
ion get you
You would have probably gotten a simplified response if you asked in the beginner channel. This question doesn't really belong here.
oh okay
I need some advice related to programming or architectural pattern for a problem I face.
Essentially, I currently use something I would call a "deferred builder", and I have a problem expressing it in C#.
There are two kinds of objects: managed children and Uber object (modeled by a tree rooted at Uber object). Children don't function without the Uber object, so there is a strong coupling between the two.
My use case is basically this: uber object performs some kind of work and composes a final result, while children define what kind of operations are performed on data/context provided by uber object in a composable way. So children in reality expose "some function of input and context".
Now, I would essentially want to represent some kind of "pipeline" as well as it's requirements.
For example assume I have a root object Root and some objects A, B, C that transform data like so (this is a mental model, not real function definitions):
A: (int) -> (int)
B: (int, string ctxValue) -> Result
C: ((int) -> Result, string ctxValue) -> (int) -> Result
A is just a simple child that transforms int into int. indempotent.
B is some operation that transforms int into Result, but also depends on some kind of context value that would be supplied by the Root when the actual calculation is performed. It's context sensitive.
C is some higher level operation, that transforms one data pipeline into another, in this case (int) -> Result function would be transformed into another (int) -> Result function.
I am not proficient in functional programming, but as far as my knowledge goes this has something to do with monadic composition?
So now I have this use case:
Root knows how to compose the A,B,C and would construct a pipeline that essentially evaluates (int) -> Result by doing with C(BβA) (the dot is a notation for function composition i.e. (BβA)(x) === B(A(x))).
And here lies my problem: How can I express that BβA is a valid composition, even though B depends on an additional context value that is not yet known, but will be known and supplied by Root when the actual calculation takes place?
My current approach is defining a base Requirement class and each function would export both a "function" (wrapper object with apply method) and a mutable Requirement data object, that is "filled in" in the Root and the apply function uses it in it's context.
Look at βdataflowβ and βpipes & filtersβ architecture styles, those should discuss your issue in the abstract
Typically you need a dependency resolver that orders the graph so that all nodes have all their dependencies when triggered
Not all graphs are serializable (thatβs the technical term for it) and therefore exhibit race conditions
You need to design your system such that these contentions are prevented, handled or at least easy to find in debugging.
Fundamentals of concurrency might also be informative (the CS theory and archetypical problems behind it)
The monad is just one way to evaluate the functions partially such that you can inject the missing bits later
It does however not fundamentally solve the issue
Itβs just one way of thinking about it
If you have pure functions and monadic structure you skip many of the common pitfalls of stateful concurrency
But those are very limiting
effectively you would be constructing something similar to a shader graph
yeah, thanks for naming the pattern, I was missing this bit of info. The pipes and filters is mostly what I'm trying to achieve on high-level. As for graph and concurrency I have it rather easy, because right now graphs are as far as I'm concerned trees or DAGs somewhere in the future and I also don't (and most probably won't) need to bother with concurrency
well, if you have a tree/dag with just one branch or any kind of events, you have concurrency
essentially this is a simplified version of what I'm doing currently, only that it's mostly a tree
It has to be a tree, anything else is impossibly complicated π
Also Check out PD, VVVV and max/msp
VVVV, with its language VL in particular is a fully visual/node-based representation of C#
That seems awfully lot like currying.
currying with extra steps, due to context
I found VVVV, I don't know what PD and max/msp are though
Same thing
Less fancy though
itβs what many βvisual artistsβ and VJs use
itβs particularly interesting because they deal with the whole desire of having such graphs not be a tree
If you just curry your parameters:
A: int -> int
B: int -> ctx -> result
Then you can simply compose them into B (A(input)) (ctx).
B (A(input)) becomes ctx -> result.
and thus the monad rises
that functional approach will get terribly ugly when that structure is supposed to do anything to the outside world
I'm not sure that has anything to do with monad, but I'm also not familiar enough with functional programming to really talk about it.
I'm just commenting on that what they initially talk about is pretty much exactly currying.
Currying could be helpful, that's true, but it's also true that it can become pretty ugly and hard to work with later on. I can also imagine C# would make it especially difficult, as all curried functions would require their own flavor of generic method due to the lack of type inference that is present in functional languages. I think there would also be yet another problem in the case of the object C: as far as it's concerned, the "context requirements" for the composition of BβA should bother it, and it should be able to just "propagate" them outside.
Eh, I'm not sure how that factors into each other.
Currying is merely the concept of changing Func<T0, T1, TR> into Func<T0, Func<T1, TR>>.
Currying:
Func<int, int> Add(int x) => y => x + y;
var addThree = Add(3);
var result = addThree(4);
I guess the more OOP way is to write:
class Adder
{
private int _x;
public Adder(int x)
{
_x = x;
}
public int Add(int y)
{
return _x + y;
}
}
var addThree = new Adder(3);
var result = addThree.Add(4);
Granted this is a very dumb example, but I'm merely pointing out that currying is not some giant deep black magic that causes you to completely shift your way of thinking and writing code.
(In fact the class Adder way is harder to compose in C#, because C# lacks a way to type constructor so there's no way to pass around classes to construct them)
ah, yeah, no worries, I am familiar with currying from CS background, I just read a bunch of SO or blog post I can't find for some reason again and their exampel looked pretty verbose, and they as well as people in comments were referencing additional libs specifically for currying, so I just included what they wrote
Yeah, not that I would actively use currying in C# either because well, C# is pretty rooted in OOP.
If you want a more OOP way of achieving the same thing as in your original example without currying, you would probably write something like:
interface IA
{
int Run(int foo);
}
interface IB
{
Result Run(int foo, CtxValue bar);
}
// Optionally implement an interface IC
class C
{
private IA _a;
private IB _b:
// constructor...
public Result Run(int foo, CtxValue bar)
{
return IB.Run(IA.Run(foo), bar);
}
}
Now you have a way to compose A+B into C via new C(new A(), new B()).
Ah, but you can now see a problem: there is now a strong dependency between C and B, because C inherited what is essentially a part of B's only signature! This is somewhat similar to prop drilling. But I was thinking about a similar approach a while ago, only that CtxValue, now called Environment, would be passed or defined in a closure of all of the children, and it's up to the Root to correctly initialize/pass it Environment.
Some cons of that (depending on implementation): runtime checks (but I guess it either way cannot be done solely on the type level as the "tree" can be dynamic so there is no way to know the type for curried/partially applied function in advance), mutability of the environment (unless it's handled by some clever "EnvironmentBuilder" or "Maybe" kind of type), and possibly a bunch of boilerplate in each child.
Yeah which is why currying solves it so nicely, if you have to compose a bunch of stuffs and they all want one thing in common to be passed down, you would simply curry that (ctx -> input -> result) to the front/to the end, so that essentially brings the ctx all the way up to the root.
yeah, good observation
And the OOP way of solving this problem is via dependency injection.
yeah, zenject? or what is it that is recommended for unity? Never used DI in unity project yet (although DI in that case would be an overkill imo)
DI is just a design pattern really, all those frameworks do is cut down the boilerplate
yeah, but they also work with unity already, and if I had to do it all over again I would have to know all the quirks (and unity has lots...)
serialization, prefab stages, initialization, domain reloads etc are just single examples that make hand-written DI a bit more complicated imo (but again, I didn't use it, I just know that these cases were problematic in other similar situations)
the main feature of DI frameworks is instantiating and looking up dependencies, all the extra stuff in zenject is bells and whistles that i (as a long time zenject user) wouldn't touch with a barge pole π
so basically, it's a fancy way to call constructors most of the time
in fact, these days i'd usually go with vcontainer instead, since it gets rid of most of the extras
the sheer length of the readme is frightening
Important question, how much garbage creates or how slow is the NativeArray<>.GetSubArray(); method?
Is it shit if i run it multiple times?
https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeArray_1.GetSubArray.html
i believe it is just offesting the pointer and return a new struct, verify it by checking the pointer value
Native memory is never garbage. Garbage is only a concept inside C#'s world of garbage collected managed memory. With Native collections you must manage the memory yourself.
Indeed that method merely gives you back a view of part of the existing array.
well, you're still getting that native memory from somewhere...
a persistent allocation is pretty much just a malloc, afaik
(unlike a temp allocation, which is taken from a scratchpad allocator that's trivially freed after each frame)
but it'll be handled entirely separately from C#'s managed world, yeah
oh right, duh. that's not GC'd
π€¦
Perfect, and what about Concat two native arrays? The docs seem to indicate that it creates a copy
I do not see a "Concat" method
I guess then it automatically uses this? https://docs.unity3d.com/2018.1/Documentation/ScriptReference/Array.Concat.html
no
I can concat two nativearrays in unity, which is weird also because the original data gets modified too
are you importing Linq by accident?
if you do array1.Concat(array2) with Linq, you're not modifying either array, you're creating an enumeration of them both
yeah -- which will be an IEnumerable<T> for two NativeArray<T>'s
not usable in unmanaged code, but you can certainly do that to iterate over several native arrays in C# if you want to
I think i am yes!
So I'm confused
Can i pass that into a job and does it create garbage?
no, and yes!
if you need to concatenate two arrays for a job, you need to make a new array and copy them into it
Damm, alright
can I force unity project/C# compiler to emit errors and respect #nullable enable pragma? I would like to ensure strong nullability...
You need to turn on NRT (which will emit warnings) and also warnings as errors.
How to decelerate nav mesh agents when they approach the destination? Should I code myself or it has been implemented?
It does not work. nav agent stops instantly when they reach
You also need a stopping distance.
in the documentation for navmeshcomponent there is an excellent bit about advanced controller which does that.
I have implemented by decreasing speed based on remaining distance. It is OK
agent.speed=Lerp (0.2,max_speed,remainig/5f)
Is there something I'm missing for adding curves to an animation clip from code? I'm trying to edit/add curves to this menu and while I'm able to see it in the animation tab itself, it's not showing up here on the fbx animation tab. I'm using the AnimationUtility.SetEditorCurve(Clip, bind, FootstepCurve); method from a script to do this.
nvm, I figured it out thanks to this thread: https://forum.unity.com/threads/setting-modelimporters-clipanimations-clears-events-for-all-referenced-clips.222914/
is there anyone that knows about splines, and if i can get a rb to snap to them whilst it moves
Last I checked, I don't think the built in spline package has rigidbody snapping. However you can check out the Dreamteck asset, which does.
Thanks to the "pipes and filters" name I found this great material by M$ for various advanced architectural patterns:
https://learn.microsoft.com/en-us/azure/architecture/patterns/pipes-and-filters
So thanks again!
I like the Reflex DI, it's pretty minimal, the devs are active, works like a charm, it's faster than vcontainer or any other DI framework, with less GC
Never really liked zenject, there is just so many useless things that no one really uses
this one's readme doesn't make my computer run out of memory, so that is promising
Hey! I'm trying to make an attribute system where they can be applied a modifier and they will keep in a list, calculate the total value of the attribute, emit a signal and i also wanted it to be able to remove that modifier after a delay, but i dont want this to be a monobehaviour. Any way i could use an Async Await for achieving this?
got it thanks
events
any reason why you want to async it? Why let your player wait for stats to update when they equip their item.
no no, i want to remove them if they have a time to be active
will come in handy for buffs and stuff
btw you can use Task.Delay for it
oh, so you want a constant effect going on
I feel like you'd just want to use coroutines to be accurate as possible
cant because it isnt a mono behaviour
make a BuffManager singleton
Wasnβt Unity making Awaitable or something
for me sometimes all i need is less update loops in random places
i figured there must be a way and someone would help out if i didnt
oh yeah I heard awaitable is pretty accurate
Async/await isn't inherently more or less accurate than coroutines. You can make coroutine power async/await and get exactly the same behavior.
To be fair Task.Delay can be less accurate since it has no knowledge of game time or time scale
Sure but that's not the only way to time things with async/await.
Yeah itβs not Taskβs problem π
Yep.
Although for this case I don't think async/await is necessary, it seems like simply having an end time property for each stat will suffice, since you are very likely to have to do something in update anyways so just check the end time there.
What should be the best way to separate a string containing 3 variables:
string s = v1 + v2 + v3;
When v1, v2 and v3 is of unknown size and I dont want to separate them by a character.
this isnt an advanced issue, regex will be your easiest solution. Although you will need some structure to this string, for example "1111" cannot be solved. Either v1 v2 or v3 can be 11
storing stuff in strings and reading it back is a pretty bad idea though (unless related to saving or other stuff). use a class or struct depending on the use
Sending some stuff as a packet
string -> bytes
bytes -> string
And I dont want to restrict any of the variables to a specific length either, so storing the length as say the first byte isnt really viable either.
then its more of a #archived-networking issue but really there are networking frameworks already which can just take a custom class, serialize it for you, then send it over the network. You shouldnt be making your own unless you really know what you're doing.
Anyways this #archived-code-advanced message is still an answer to your initial question.
Alright, thanks.
There's no good reason to send integers as strings through network packets. You can send them as four bytes. Every int is 4 bytes, regardless of what their value is.
Yeah no I am using bytes.
But I ended up using the first two bytes to specify my first to variables and then the rest for variable 3.