#archived-code-advanced
1 messages · Page 103 of 1
so add a script to each piece which does describe it's walls and exits
Or maybe I could add an empty gameobject to where the wall opening is and check which gameobjects overlap
If two empty gameobjects are im the same position it means they’re connected
problem is with that approach, you need to have placed the room first before you can check
you really do not want to be instantiating a room until you KNOW it fits
Oh so you think its better if i dont instantiate the room if its going to block an area
problem is, how do you know if that block is going to do that?
absolutely, unless that is part of your game strategy
No i dont want to block areas
Say each room has 4 bools, N,S,E,W. each one can be true (is a wall) or false (is an exit).
now you can compare a random block against it's neighbours
What do i look for?
Cause I need to check if that room blocks an area of the maze and it’s nit generated yet
well. this.N == roomNorth.S, this.S == roomSouth.N, this.W == roomWest.E and this.E == roomEast.W
obviously if there is no room at any one of those positions then the result of that test is always true
I’don’t get it, isnt N, S, W and W a bool? And if i compare those values ill get true if they both have a wall or if they both dont
exactly, so wall will always match to wall and exit will always match to exit
the way I do this is to use the following logic
bool?[] walls; // true is wall, false is exit, null is no room at position
then loop through the neighbouring rooms and fill that array with their S,W,N,E values // From North clockwise
then check all of my rooms that fit the array and write them to a List
randomly select from the List made
the room selected will always fit the space
I’m gonna try thanks
Any suggestions on how to check if a NativeList is null? .IsCreated just throws a nullref exception if you call it on an uninitialized NativeList
public struct SimulationState : IEcsAutoReset<SimulationState> {
public NativeList<EntityPosition> Positions;
public void AutoReset(ref SimulationState c) {
if (Positions.Length > 0 || Positions.IsCreated) // Either of these checks throw a nullref error
c.Positions.Dispose();
c.Positions = new(Allocator.Persistent);
}
}
And if I try to call Dispose() immediately, it throws an exception saying that the list hasn't been allocated yet (which is true obviously)
IsCreated should return false on an unallocated native collection. In the code snippet you're checking it after trying to retrieve Length, which will throw an exception.
Thanks for taking a look. Unfortunately just doing
if (Positions.IsCreated)
c.Positions.Dispose();
c.Positions = new(Allocator.Persistent);
also throws an exception
I'll paste it, sec..
NullReferenceException: Object reference not set to an instance of an object
Unity.Collections.NativeList`1[T].get_IsCreated () (at ./Library/PackageCache/com.unity.collections@1.2.4/Unity.Collections/NativeList.cs:509)
***SimulationState.AutoReset (***.SimulationState& c) (at Assets/***/Scripts/Simulation/SimulationComponents.cs:33)
IsCreated is itself just a null check really so i don't see how it could throw 🤔
Yeah that's what's throwing me for a loop too
This is the offending line
public bool IsCreated => m_ListData != null;
and m_ListData is defined as
[NativeDisableUnsafePtrRestriction]
internal UnsafeList<T>* m_ListData;
it's worth noting that in my version of the package at least, line 509 is inside Dispose, so are you sure it's not that IsCreated is returning true but the list is pointing to bad data?
At this stage I haven't actually done anything to the list yet 🤔
AutoReset is called automatically from the ecs system when this component gets reused, and is used for cleanup
So ideally I'd just initialize it once and then Clear(), but there's no way of checking if it's already been allocated
Debug.Log(Positions.IsCreated); throws the same error
Is there a reason why you're checking Positions, but disposing c.Positions?
Ahhh
I don't know how that explains the exception, though.
You're right, I wasn't poking the new component. Let me see if I can untangle this..
Doink 🤡
if (!c.Positions.IsCreated)
c.Positions = new(Allocator.Persistent);
c.Positions.Clear();
All good
Nice. Still a weird exception, though.
The only thing that can be null is the m_ListData pointer, but the only way it's used is in a null check.
Ah okay, I thought there might be more to it. That's weird then
Everything runs smoothly now though, thanks again
Not sure if this is advanced, but probably. If you take a package to overwrite its scripts (because its needed), do you need to copy the whole package or are you able to overwrite just individual script files somehow too? Guess not, but thought it might be worth a short asking here.
if you want to modify a package, the entire package will need to be embedded into the project
https://docs.unity3d.com/Manual/upm-embed.html
Dang it, thats what I was not hoping... thanks for clarification. Guess I have to live with the dirty way and not finished packages from unity side until they fix it themselves.
I've got an asset from the asset store that is using hardcode paths to the root asset folder to dump a generated file that just confirms you've seen their little popup thingy after install. I always put my third party stuff in a "ThirdParty" folder but this asset keeps regenerating this useless file in my root so I'd like to fix it for them so its using relative paths and not messing up my beautiful folder hierachy lol
Whats the best way to detect the asset's current path relative to asset root folder to I can make it generate this folder within itself each time?
I was thinking adding a dummy file to the asset's subfolder with a unique file extension, then searching that file from the asset database to get its path and then editing their script to use that relative path. Is there a better way?
also might make more sense to use https://docs.unity3d.com/ScriptReference/EditorPrefs.html
Ah ok. So really they should just create their own editor pref like a simple bool and just check for and set it as needed?
if that's all the file it generates is doing then yeah, just set a "has seen the popup" bool in editorprefs
yeah thats all it is, just confirms you've seen their greeting.
ok awesome thank you. Thats pretty clean
You still know where the walls are since you placed them. What you need is some sort of data monobehaviour that keeps track of what direction is open to move to.
Coroutine Best Practice: WaitUntil vs. While-loop yield return null
well damn, that sucks. They have these hardcoded paths peppered all through their assets
they are using it for generated content as well
Maybe I could create a utility editor class singleton that hooks into [InitializeOnLoad] and keeps paths there. Just need to figure out the best way to have the editor class get its own asset path and use that to get the relative path to Assets root, and then update all their path code to build relative paths using that utility
tbh, I would contact the asset publisher and tell them to damn well fix it
I'm planning to but they have several assets and all 3 that I have do this so I'm hoping to just say hey here's a patch, mind merging? lol So I don't have to redo these each time they update
wow, I wish my users were as dedicated as you, mine just say 'Hey, Steve fix this'
Hello guys, this is not connected to Unity, but maybe you can give me some hint.
I need to parse and modify spir-v bytecode. Do you have any code samples for that?
spir-v is a pretty well defined spec should be possible
but question is why not go back to the source level and work with what ever generated it in the first place
Hello all! I'm using R3 + UniTask for my project and I need to implement feature:
in my game there is a turn state, when it changes some modules reacts (being subscribed to ReactiveProperty), for example there is a module that draws 2 cards at the beginning of each turn, also there might be a module that asks player to select a free card as a reward each 5 turns, both of those modules callbacks are async UniTask which means that I actually need to await them before change turn state to next turn.
Basically code which requests end of turn looks like this:
private readonly ReactiveProperty<ETurnState> _turnState = new(ETurnState.None);
public void Turn()
{
_turnState.Value = ETurnState.End;
}
In perfect world I would do something like:
public async UniTask Turn()
{
await _turnState.Set(ETurnState.End) // await all async callbacks reacting to end of turn
// initiate next turn
}
You could manage subscriptions yourself rather than using ReactiveProperty
Something like List<Func<Task>> TurnEndTasks ?
yes, this will work, but I'm looking for solution which will be consistent with R3 API if it is possible
You'd need your own. You can wrap that to make it look like observable interface,
But in reality it is not, because observable should not behave different because of subscribers
You want some bidirectional messaging, I don't think reactive extensions would/should cover it
Good point. Well, how can I organize it better then. What I want basically to achieve is to have game rules like Draw N cards each turn / Draft N cards each M turns as modules I can add and remove through my game config. That is why THEY should subscribe to some turn state (or just to Subject<Unit> NextTurn doesn't matter). List<Func<Task>> as custom awaitable ordered way to call async methods is good for me. Would be ok this way or should I figure out something more clean?
I don't think anything is blocking to do so? I would wrap it to look like the code you wrote but do something roughly underlying:
Task ProcessValue(T val) =>
Task.WhenAll(_subs.Select(x => x(val)));
So that your rules can be one of the subscribers
Though not sure you want it ordered or parallel 😄
Ordered, so when all fits my requirements
Hello, i initially created 2 tags that are still displayed in the object tag list, but not in the "added tags" list anymore.
I'm also unable to recreate the tags that are still displayed in the object tag list. I guess it's a bug, but is there any workaround that i could use?
Sorry if i'm not in the correct channel, i dont see any "support/bug" channel
those are default tags, not ones you added
but yes, #💻┃unity-talk for issues not related to code
I'm truly sorry, i was 100% sure that i created those two tags before, i just checked in another project, and yes, those tags were created by default, my mistake.
Thanks for the help, and sorry for the bad channel use.
Having some new issues when trying to serialize a NativeList to be sent over the network.
public struct WrappedPositions : INetworkSerializable {
public NativeList<Vector2> Positions;
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter {
serializer.SerializeValue(ref Positions);
}
public override string ToString() {
return $"[Positions has {Positions.Length} entries]";
}
}
void MessageTest() {
// Prepare test message
var message = new WrappedPositions() { Positions = new(Allocator.Temp) };
message.Positions.Add(Vector2.right);
// Prints "[Positions has 1 entries]"
Debug.Log($"{message}");
// Write message
using var writer = new FastBufferWriter(1024, Allocator.Temp);
writer.WriteValueSafe(message);
// Read message
using var reader = new FastBufferReader(writer.ToArray(), Allocator.Temp);
reader.ReadValueSafe(out WrappedPositions result);
// Throws "ObjectDisposedException: The UNKNOWN_OBJECT_TYPE has been deallocated, it is not allowed to access it"
Debug.Log($"{result}");
}
Same result if I try to give the reader a pre initialized NativeList
...
// Read message
using var reader = new FastBufferReader(writer.ToArray(), Allocator.Temp);
WrappedPositions result = new() { Positions = new(Allocator.Temp) };
reader.ReadValueSafe(out result);
...
Everything works nicely with other standard types, like a single Vector2 instead of a NativeList
Unity documentation says it's doable...
https://docs-multiplayer.unity3d.com/netcode/1.8.1/advanced-topics/serialization/arrays/#native-containers
Arrays of C# primitive types, like int], and [Unity primitive types, such as Vector3, are serialized by built-in serialization code. Otherwise, any array of types that aren't handled by the built-in serialization code, such as string], needs to be handled through a container class or structure that implements the [INetworkSerializable interface.
i don't think using ReadValueSafe works here, since it's an out param it has to reinitialize whatever the reference is pointing to when you call the method, so you're losing the reference to the list you initialize before the call! there's ReadNetworkSerializableInPlace which i haven't actually used before but that might be what you need?
since it's not a *Safe method, i guess you also need to know the length ahead of time and call TryBeginRead yourself
Interesting...
I'll poke around with this
Huh
So that got me a little closer! This seems to work, although I'm grabbing the NativeList inside the struct directly;
void MessageTest() {
// Prepare test message
var message = new WrappedPositions() { Positions = new(Allocator.Persistent) };
message.Positions.Add(Vector2.right);
// Prints "[Positions has 1 entries]"
Debug.Log($"{message}");
// Write message
using var writer = new FastBufferWriter(1024, Allocator.Persistent);
writer.WriteValueSafe(message);
var writerBytes = writer.ToArray().Length;
Debug.Log($"Writer has ({writerBytes} bytes)");
// Read message
using var reader = new FastBufferReader(writer.ToArray(), Allocator.Persistent);
WrappedPositions result = new() { Positions = new(Allocator.Persistent) };
reader.TryBeginRead(writerBytes);
reader.ReadValueInPlace(ref result.Positions);
// Prints "[Positions has 1 entries]"
Debug.Log($"{result}");
}
Ahh okay, yeah it did work with ReadNetworkSerializableInPlace, as long as I know the length like you said!
So I guess I need to pack that with the network message itself
...but at that point, you might as well just use an array
Good morning,
I want to create a voxel game.
Currently I'm facing a problem and I can't find any way to do this:
I want to have several voxel maps for example:
map 1
map 2
the player can choose one or the other.
To create these maps of different sizes, I am completely blocked, with some research, it is often recommended to generate a voxel grid.
I have trouble seeing what happens next, that is to say that currently I know how to generate a terrain based on perlin, but how can I "keep" this generation to add decoration?
At this level, I was told about json files to place the elements, which seems super boring.
The way I see things I would like for example:
map1: 150 x 150 x 10 voxels
map 2: 100 x 100 x 5
So an efficient system for “generating” maps based on certain values.
Can anyone guide me?
I'm not sure what json has to do with procedural generation.
There are many ways to turn your voxel data into actual object. heightmaps based generation and marching cubes are two common approaches. Then there are many other algorithms for anything extra you might need, like placing vegetation and other assets, creating caves and rivers, and such.
I don't need procedural generation , map are fixe
Ok, then I don't understand the question
To put it simply, I'm having trouble knowing how to generate maps of different sizes and heights so that they can have their own decorations.
I use perlin for ground generation and add variations.
See it like call of duty maps, but voxel version
With 3D, I know how to do it, the problem is that the generation of voxel terrain is written in C# code, where in 3D I can simply add terrain in the scene and save it as prefabs
So currently I have for example a generated map of 100x100, to which I can add decoration, but how do I save the whole thing?
what "whole thing"?
And what do you mean by "decorations"?
And what does it have to do with C++?
Well, you place them. Either procedurally or manually
To repeat what I said with call of duty, I would like to create a map on the theme "funfair" and another on the theme “forest of trees”
Except that currently I am generating a world, which I do not know how to preserve
So what exactly are you asking? How to save your generated map? Or how to place "decorations" on it? Which is it?
Well, I told you how to place "decorations".
As for saving it, you can serialize the data as a json or binary and save it to a file.
thanks I'll look for serialisation
How do I load async from the resources folder using the new awaitable approach?
I rather not use a coroutine.
ResourceRequest request = Resources.LoadAsync<TForm>("Prefabs/UI/Forms");
await request;
var prefab = request.asset as TForm;```
Will this do the trick?
😭 I have another 4 or so hours before I can test.
I am in the middle of a large refractoring process.
i have a tps character and im using a state machine, should i create a state for my character's aim state or should i check if im aiming in other states (if anyone can help i can send you the project, because something feels wrong)
the character's movement system changes while aiming
Would like to share my solution with other people, in case someone finds himself in the same position as I was. It might not be the best approach or the fastest but it works.
Hope it can be useful to other people in the future https://gdl.space/otokogapid.cs
hello guys i have a question
im working on project for computer science final and one of the requirements is "searching or sorting (from iterative algorithm)". so i was WONDERING if GameObject.FindObjectOfType<>(); or one of unity's built in search functions is either a linear search or binary search or someething?? thnaks
Not really a #archived-code-advanced question but the actual answer is we don't know since FindObjectOfType is closed source. Also it's UnityEngine.Object.FindObjectOfType not GameObject
It's widely theorized to be a linear search.
Hey all, is there any way I'd be able to somehow hack in new C# features into Unity? (things like global using directives, new array initialisers, etc.)
sort of, you can upgrade roslyn in your project (which is not supported, but there are a couple of third party tools that help you do so) to get newer c# features that don't require newer .net versions.
you can also copy type definitions for a lot of things into your project from the c# source
none of that is supported or really recommended (for the most part)
is there a good way to get the capsule position when it hit something from a capsule cast?
im trying to snap a capsule downward, i was doing trig to get the behavior i wanted but it was shakey (maybe as a result of inaccuracies?)
i need to get the blue point here, where the capsule above is the starting position, and the dotted capsule is where the capsulecast intersects with a plane
the raycasthit from the capsule cast returns the red point in the .point property
which makes sense, but what i really want is that blue point at the center of the capsule
RaycastHit should have info to this or at least info to calculate this
what property? the red point is in there but i dont see any way to get the blue
oh i guess i could use the normal to get the center of the sphere
It is not well-documented, but it behaves differently per Ray/Sphere/etc
ohh... wacky
Let me see if I can find
But I think you could use origin + direction * hitInfo.distance to get that center point
https://docs.unity3d.com/ScriptReference/RaycastHit-distance.html
Ah here it is
In the case of a swept volume or sphere cast, the distance represents the magnitude of the vector from the origin point to the translated point at which the volume contacts the other collider.
ah ty!
I've built a script to connect to an API service via a websocket connection.
I need help on handling methods when I receive messages back.
Here's the script with only the parts that matter:
{
switch (baseMessage.type)
{
case "audio_output":
Debug.Log("Message type received: Assistant Audio");
HandleAssistantAudio(e.Data);
break;
}
}
void HandleAssistantText(string jsonData)
{
var message = JsonConvert.DeserializeObject<AudioOutputMessage>(jsonData);
string base64String = message.data;
Debug.Log(base64String);
SaveText(base64String); //This generates the error
}
void SaveText(string content)
{
string filePath = System.IO.Path.Combine(Application.persistentDataPath, "newText.txt");
System.IO.File.WriteAllText(filePath, content);
Debug.Log("Clipboard text written to: " + filePath);
}```
This is the error I get:
```Exception: UnityEngine.UnityException: FindObjectsOfType can only be called from the main thread. Constructors and field initializers will be executed from the loading thread when loading a scene. Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.```
I need a way to execute that code on the right thread but don't know how to do it.
How are you sending this request? Normally you'd use UnityWebRequest.
To run code on the main thread search for "unity main thread dispatcher", there are several solutions.
Note that your SaveText method is prone to fail anyway. Any I/O operation MUST be enclosed with try/catch because it can fail for a variety of reasons on any system, such as permissions, some other app locking the file, or running out of disk space.
The distance property
That's what you want
NVM I'm slow
one thing you dont want to be doing is Application.persistentDataPath. cache the value first
and I would suggest there is something in your AudioOutputMessage class that Unity does not like
Thanks for the suggestion, I've changed the method since the thing I truly need to do is to convert that base64string into an audioclip, but seems an impossible task to do
The documentation is unexistent and there are very few thread that discuss this topic with methods that are obsolete or don't work at all nowadays
{
var message = JsonConvert.DeserializeObject<AudioOutputMessage>(jsonData);
string base64String = message.data;
AudioClip audioClip = Base64ToAudioClip(base64String);
}
private AudioClip Base64ToAudioClip(string base64String)
{
byte[] audioBytes = System.Convert.FromBase64String(base64String);
float[] audioSamples = new float[audioBytes.Length / 4];
Buffer.BlockCopy(audioBytes, 0, audioSamples, 0, audioBytes.Length);
AudioClip audioClip = AudioClip.Create("GeneratedAudioClip", audioSamples.Length, 1, 44100, false);
audioClip.SetData(audioSamples, 0);
return audioClip;
}```
This are the current methods I have, I still cannot test it cause I have the thread topic to solve first
I don't think it's impossible. What you need to know is how the audio was converted to base64 in the first place and just reverse the steps
Hi, I'm new to Jobs/Burst, and everytime I spawn or destroy a unit, I re-setup the arrays, and I have 2 questions, isn't that expensive? And how do other developers do it?
Well, for one, you could reuse the arrays instead of disposing and recreating them. You just need to clear them.
And two, I'm not sure why you even need arrays of data for one unit? Unless you mean something else by a "unit"?
Thanks for the reply Dlich!
How can I reuse them?
And the script in called UnitNavigationManager, so it calculates a few things for each unit in the game, if you know a better way to do this, please let me know.
what about the thread problem? how can I solve that?
this is the log:
"Exception: UnityEngine.UnityException: Construct_Internal can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function."
Well, the same way as you're using them for the previous unit..?
It's still not clear to me what a "unit" is? Is it several entities/characters?
I'm not using data path in this methods
Regarding the thread problem, CodeSmile replied to you earlier:
#archived-code-advanced message
read the second line of the message
sorry I missed that
btw I confirm that this line is the issue:
AudioClip audioClip = AudioClip.Create("GeneratedAudioClip", audioSamples.Length, 1, 44100, false);
I can't use a webrequest, its a websocket connection
This is the class, seems pretty simple to have errors
{
public string type;
public string id;
public string data;
}```
it just gets the json data I receive from the message
The issue is that you're using unity API on a background thread. That is not allowed. You need to sync to a main thread before calling it.
"data" containts the audio in form of base64
Thank you for the reply again. I think I'm starting to understand how this works.
Ok, what should I do instead?
where can I search for examples?
its the first time I handle a websocket connection by myself
I have to somehow detach from that thread and do stuff on main I guess
but how? that is nowhere near enough information
That's what CodeSmile told you about. "Unity main thread dispatcher". Although you can also do it yourself. For example have a flag(bool) set to true on message received and data cached and call the unity api from Update or another callback executed on the main thread and execute your logic when the flag is raised.
I've tried to put that string I receive on different online converters and it works, so I assume there is a universal way?
Convert audio to Base64 online and use the result string as data URI, HTML object, JavaScript Audio, and others
do you not understand, you need to know HOW the process is done in order to reverse it
indeed, can't find anything in the documentation about it tho
guess I'll first try to fix the thread stuff
maybe I can read about it on these sites
then you are reduced to trial and error
since they seems to use the same system
this works too
https://base64.guru/converter/decode/audio
Convert Base64 to audio file and play it online or download it to your device
all well and good. if they are doing a straight byte[] to base64string and back again. problem is AudioClip is expecting a float[]
Ok so one step at time, I've fixed the thread issue, I've made a super rudimental script that checks every update if a string gets filled and when it does it tries to process the data into an audioclip. I know that's not ideal but I'll take care of it when the rest is solved.
using System;
using UnityEngine;
public class GenerateAudio : MonoBehaviour
{
public HumeWebSocket humeWebSocket;
public bool processingAudio;
public AudioSource audioSource;
void Update()
{
if(!string.IsNullOrEmpty(humeWebSocket.audioString))
{
if (!processingAudio)
{
processingAudio = true;
Debug.Log("Generating Audio");
AudioClip newClip = Base64ToAudioClip(humeWebSocket.audioString);
audioSource.clip = newClip;
audioSource.Play();
}
}
}
AudioClip Base64ToAudioClip(string base64String)
{
byte[] audioBytes = Convert.FromBase64String(base64String);
float[] audioSamples = new float[audioBytes.Length / 4];
Buffer.BlockCopy(audioBytes, 0, audioSamples, 0, audioBytes.Length);
AudioClip audioClip = AudioClip.Create("GeneratedAudioClip", audioSamples.Length, 1, 44100, false);
audioClip.SetData(audioSamples, 0);
Debug.Log(audioClip.name);
return audioClip;
}
}```
So far I get no error but an audioclip that is just noise.
Now its time to figuring out how to decode that string.
I have a possible hacky method for you
- Convert base64string to byte[]
- save byte[] as file
- use UnityWebRequest with the file:/// protocol to read file from 2)
- Get the response as an AudioClip
Horrible I know but it should work
Oh so UnityWebRequest works locally, intersting
I don't think that will be doable once played in webgl tho
sure it will
other option is not to send the audiodata via the websocket but to send the URL of the audiofile and then use WebRequest to get it
I dont think think this new api service I'm testing is doing it.
on current system I'm using DownloadHandlerAudioClip and thats perfect but only works wit URLs
just to check, are you sure the frequency, channels etc all match the format of your data?
I'm a little confused, do you have no control over what the websocket send's you
No, its an external service
so you really have no idea of the data format of the audio file
Since there's no documentation about it, I've downloaded the decoded file from one of the website I mentioned above, it was 24000Hz so I updated that value in my script but it still isnt right
I've sent a message and directly asked them about that and all the necessary steps I'll need to do in order to decode the string
Hope that is the last piece of the puzzle
From good to bad:
- Reuse arrays every frame
- Allocate arrays with Allocator.Temp
- Allocate arrays with Allocator.TempJob
- Allocate arrays with Allocator.Persistent
Thank you @brave cairn !
Allocator.Temp no need to be disposed, but can't be used in across job boundaries.
I have this job that executes int and TransformAccess, however I'm having issues scheduling it, can you please tell me what I'm doing wrong?
Thanks for the tip!
Sorry @brave cairn , I don't follow
You are scheduling job with unitsCoresList.Count as first paremeter. But IJobParallelForTransform.Schedule function does not accept count parameter.
Ohh, I see. I cannot use TransformAccess and Integer together with a job then
You can pass your integer as job parameter. Just like deltaTime
Like this?
No. Like this:
struct MovementJob: IJobParallelForTransform
{
public int unitsCoresCount;
public float deltaTime;
...
}
var job2 = new MovementJob()
{
unitsCoresCount = unitsCoresList.Count,
...
}
job2.Schedule(...);
@upbeat path I've made it!
using UnityEngine;
public class GenerateAudio : MonoBehaviour
{
public HumeWebSocket humeWebSocket;
public bool processingAudio;
public AudioSource audioSource;
void Update()
{
if (!string.IsNullOrEmpty(humeWebSocket.audioString))
{
if (!processingAudio)
{
processingAudio = true;
ConvertIntoAudio(humeWebSocket.audioString);
}
}
}
void ConvertIntoAudio(string base64String)
{
// Decode the base64 string to a byte array
byte[] audioData = Convert.FromBase64String(base64String);
// Create an AudioClip from the byte array
AudioClip audioClip = WavUtility.ToAudioClip(audioData, "audioClip");
// Play the AudioClip
audioSource.clip = audioClip;
audioSource.Play();
}
}
public static class WavUtility
{
// Convert byte array to AudioClip
public static AudioClip ToAudioClip(byte[] wavFile, string name)
{
int channels = BitConverter.ToInt16(wavFile, 22);
int sampleRate = BitConverter.ToInt32(wavFile, 24);
int subchunk2Size = BitConverter.ToInt32(wavFile, 40);
float[] data = new float[subchunk2Size / 2];
for (int i = 0; i < data.Length; i++)
{
data[i] = BitConverter.ToInt16(wavFile, 44 + i * 2) / 32768f;
}
AudioClip audioClip = AudioClip.Create(name, data.Length, channels, sampleRate, false);
audioClip.SetData(data, 0);
return audioClip;
}
}```
Now I just have to pray that it works on webgl too 🙏
neat. You know this will only work for .wav files, right?
is it an issue?
every audio file I receive will be wav so its fine I guess
unless I'm missing something
I was studying my code, and don't really need to send the size of the list, because the Job will actually get the size of the transformAccessArray, isn't that right?
JobHandle handle = job2.Schedule(unitsCoresTransformAccessArray);
someone throws a .mp3 at it and it goes bang. So you might want to throw some try {} catch {} stuff in there
Exactly
ok thats surely a thing to do, but in this specific case I guess it should work 100% of times since the output is always a wav
Thank you @brave cairn !!!!
up to you but I NEVER trust data coming from the web, especially a website over which I have no control
@brave cairn It's workiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiing!!!! EUREKAAAAAAAA
I am making my own Web Socket for my VR unity game using 2 DLL libraries. the two DLLs are "websocket-sharp" and "Newtonsoft.Json". When I build the game to android everything works great until I try and open the APK. The APK opens and stays open but its stuck on a black screen. I'm assuming that I'm putting the DLLs in the wrong place. I'm also building with il2cpp.
have you run with Android Logcat to see what the problem is?
no how can i do that
install it, it's a package in the package manager
okay
don't decompile the dll's just make sure they are in a folder called Plugins
they are in a folder called plugins
and the plugins folder is in my assets folder
i installed android logcat
whats the next step
build and run. But you might just want to read the docs first
okay ill read the docs
i have built and run from unity and i have the android logcat window open
there is an error in logcat called "Not starting debugger since process cannot load the jdwp agent."
did you do a development build?
no
i opened the game and i saw this in unity "2024/06/05 14:55:04.139 17896 17919 Error libprocessgroup set_timerslack_ns write failed: Operation not permitted
"
change to development build, it's awful difficult to debug without it, and try again
okay
the build has finished
whats my next step
read what's in the log
theres a lot is there somthing im looking for
I did say to read the docs, you can filter the logs, error might be a good thing to search for
you do realize this is code advanced, we expect a little initiative from posters here
i understand. i found callbacks from my websocket saying the connection was timed out
2024/06/05 15:07:25.324 18923 18950 Info IL2CPP 6/5/2024 3:07:25 PM|Fatal|WebSocket.Connect:0|System.Net.Sockets.SocketException (0x80004005): Connection timed out
2024/06/05 15:07:25.324 18923 18950 Info IL2CPP at WebSocketSharp.WebSocket.setClientStream () [0x00000] in <00000000000000000000000000000000>:0
2024/06/05 15:07:25.324 18923 18950 Info IL2CPP at WebSocketSharp.WebSocket.doHandshake () [0x00000] in <00000000000000000000000000000000>:0
2024/06/05 15:07:25.324 18923 18950 Info IL2CPP at WebSocketSharp.WebSocket.connect () [0x00000] in <00000000000000000000000000000000>:0
2024/06/05 15:07:25.324 18923 18950 Info IL2CPP at WebSocketSharp.WebSocket.Connect () [0x00000] in <00000000000000000000000000000000>:0
i know where this is in my code but im not sure how to fix it
WebSocket = new WebSocket("ws://192.168.1.3:1534/Instance");
WebSocket.Connect();
WebSocket.OnMessage += OnMessage;
timeout is a parameter you can set for the websocket connection. You probably just need to set it higher, I generally use 2 seconds
that's a local IP address, are you sure that willl work?
right now it connects at frame one. what your saying is i should add a delay before connecting?
it does work
Not a delay, a length of time before it will be considered timing out
no, it dont know the library you're using I write my own code but timeout can be set for a websocket, it's how long it will keep the connection alive.
I suggest you read the docs for the library
Though you'll hit the timeout regardless if you don't yet have any code ever sending anything 😄
you were right it is an ip issue it works with unity but not with android i've got a plan to fix it thank you for your time 🙂
So I tested the websocket stuff I've built few hours ago and it doesn't work on webgl (it gives an error) 
I've read somewhere that could be due to the WebSocketSharp library
You need a JS library to integrate the browser WebSocket API for Unity.```
No idea if its true tho
Yeah, WebGL doesn't support background threads.
please tell me that is still possible to somehow do this websocket stuff
No clue. Probably not possible. The whole point of a socket is that it's waiting on a separate thread afaik.
Next time research your target platform limitations before moving on to the implementation
I think that somewhat is still possible with workarounds
https://gamedev.stackexchange.com/questions/176842/how-can-i-use-websockets-in-a-unity-webgl-project
I just to test them 1 by 1 since feedback could be obsolete
I mean yeah, if messing with the JS side, it's probably possible.
Have you tested it personally?
nope but I will be using it (not for webgl myself)
they aren't using the shit http in unity
note though, that asset depends on 2 other assets by the same dev, the http and tls assets because his websockets impl is built on his http and tls
I think he has just a websockets bundle with the other dependencies for like $30
Ok, thanks for the suggestion.
I will document myself on his stuff and then decide if to buy that
yeah unity's http really is ass
it doesn't even support upgrade requests websockets itself
You can remove the http part and still be right
still need the handshake and upgrade from somewhere on http
But I understand them, I guess there so few people that do this stuff that its not worth for them
websockets in webgl or websockets in general? websockets are huge
On webgl
Webgl in general is such a unused platform for things that are more complicated than 2 squares moving
(hoping that webgpu will rise interest tho)
if you do look at that dude's assets, this is his websockets bundle with the dependency assets included https://assetstore.unity.com/packages/tools/network/best-websockets-bundle-268838
Last update was few weeks ago, nice
The GitHub repo that you share earlier should work, so you don't really need any paid assets. I bet they're implementing it in a similar way anyway.
Do any of you guys employ code obfuscation methods to prevent cheating in your games? If so, how do you do so. I'm not using it for anything just curious and doing some research
Code obfuscation is not security. Any protection method you use gives exactly the amount of protection you pay for it, in the case of a free obfuscation tool, that's zero.
Clientside anti cheat doesn't work. Look at CS2, Tarkov, etc. all have massive cheater problems
valve has near unlimited money to throw at this, and people are still easily getting around it
need some help here
i'm following this guide to do source generation: https://docs.unity3d.com/Manual/roslyn-analyzers.html
but then it says i need to make a new label RoslynAnalyzer for my .dll
however, i'm using the AddressablesAssets package and I can't figure out how to label my .dll in my case
I don't follow, what does source generation do anything with addressables?
Dll will not be part of addressable asset
Source generator dll is not shipped
yea nevermind my editor bugged out and didnt allow me to set the asset label; thought it had to do with addressables changing how labels worked or something
but i still can't get the source generator to work lol
It is hard to debug for sure, I guess you have to revisit each stage and check if you done it correctly
Are you using correct version and target framework and all?
#archived-code-general message
bumped to code-advanced since i didn't get a response sorry
i think so but now i'm instead trying to isolate the issue by trying on a new project
#archived-code-general message
solved!
nevermind, i realize what i wish to do cannot be achieved due to https://forum.unity.com/threads/in-39931-scriptable-objects-generated-by-a-source-generator-cant-be-created.1438795/
This has already been reported as a bug with the ID IN-39931 but I thought I'd make a post about it so it could be more evident that this is a bug.
As...
let's say i do want to create these .cs files which are scriptable objects or monobehaviours
Oh you need .meta for that
yeap
according to the bug report i linked, i don't think they intend to fix this
so let's say im content with just generating .cs files and putting them in the folder
what are some good approaches
is there a place i can hire coders here? i need front/backend coders
Eeh could you have partial MB in your source manually then SourceGen can generate content for you?
We do not accept job or collab posts on discord.
Please use the forums:
• Commercial Job Seeking
• Commercial Job Offering
• Non Commercial Collaboration
^ Not here
for now i'm naively thinking of just writing a python script to do it, but a dumb python script wouldn't be aware of how i need to generate these files
in particular, i wish to go through a folder and pick out those .cs files whose classes are a subclass of a specific subclass (say some Factory)
and then for each of those, generate a corresponding .cs file defining a ScriptableObject
im not familiar with some of these terms
what's MB and sourcegen?
It’s just shorten term, MB is MonoBehavior and SourceGen is source generator
okay, i see what you mean
do you know a place? i am really in need
basically i have the partial classes already in the required folder
Hm if you do have partial class with meta file shouldn’t it work?
well actually if i could already create those partial classes then i trivially achieve what i want, because the .cs files i wish to generate simply contain
using UnityEngine;
namespace XXX.XXX
{
[CreateAssetMenu(menuName = "Status Effects/Bleed")]
public class BleedSOFactory : StatusEffectSOFactory<BleedFactory> { }
}
and the reason i'm doing this is because i have a generic that already works; but scriptable objects can't be generic so it is just a trivial matter of setting the generic type
Yeah it might be easier for just create some editor tool
sorry i realize this is confusing; i meant to clarify that your solution for me to already have partial classes in the folder and let the source generator take care of the rest
i can see how this paradigm can work for more complex source generation needs
with SerializedReference hack (Though I don’t like those)
but i guess my current use case is simple
I see, so if you have partial classes then you’re already done what you need. Lol
I feel like if this is small boilerplate then maybe best to just hardcode it
You could write Python script but it might take more effort than you save with it
i mean i do have like hundreds of such mono/SO classes to create
Hmm I guess one thing you can do is copying the source file from source generator intermediate directory and dump it in Unity 😦
So it can have actual meta file.. lol
true, I used this and its working
So these are all the basic steps I need to do in my webgl project, they all works but I have some inconsistency problem on the first step:
The request to get the access token (UnityWebRequest.Post) is way slower than the editor, plus something it get errors (currently working on figuring out which)
On editor 100% of the requests succeds, on webgl version they do not. I don't understand why since the code is the same
any errors in the browser dev tools network log?
I'm trying to replicate it again but now its actually working very well 😅
can I brainwash a monobehaviour to believe that it's transform is actually coming from another gameobject?
(my problem: I have a behaviour from a library that changes transform, "its own transform" and I want to affect a different gameobject)
(I know I can try to setup some "following" between game objects, but at this point I might aswell duplicate the .cs file from the library 😛 )
Just reference the other Transform and use that reference
yep, I need to duplicate the .cs file from the package and use that 😅
@azure meadow would this work for you?
public new Transform transform => someOtherObject.transform; (note the new keyword).
seems pretty heavily XY problem, like just reference the correct thing on the start, or have this object expose that wanted reference on a component
it's third party code
modify the code, or make a transform follower component
would prolly just modify the code, and makes it use a serilzied field for the target transform. then maybe if its null on Awake get the current objects transform so it still works in its old usecase
#1202574086115557446 probably will give better input
Container.BindInterfacesAndSelfTo<Employee>().FromComponentsInHierarchy().AsSingle();
var employee = Container.Resolve<Employee>();
Container.Bind<Character>().FromInstance(employee);
I want to bind child class (Employee), the parent (Character) and all interfaces. The above method is OK but I see a warning after every spawning
This installer has been assigned to the game object context.
Zenject Warning: It is bad practice to call Inject/Resolve/Instantiate before all the Installers have completed! This is important to ensure that all bindings have properly been installed in case they are needed when injecting/instantiating/resolving. Detected when operating on type 'Employee'. If you don't care about this, you can disable this warning by setting flag
I have changed the zenject method BindInterfacesAndSelfTo and add base type as well but now I see runtime errors.
public FromBinderNonGeneric BindInterfacesAndSelfTo(Type type) //baseType
{
var statement = StartBinding();
var bindInfo = statement.SpawnBindInfo();
bindInfo.ContractTypes.AllocFreeAddRange(type.Interfaces());
bindInfo.ContractTypes.Add(type);
// bindInfo.ContractTypes.Add(baseType);
bindInfo.SetContextInfo("BindInterfacesAndSelfTo({0})".Fmt(type));
// Almost always, you don't want to use the default AsTransient so make them type it
bindInfo.RequireExplicitScope = true;
return BindInternal(bindInfo, statement).To(type);
}
the warning is right, maybe it won't cause problems here immediately but you should probably avoid doing that! pretty sure you should avoid adding things you got out of the container (employee) back into it with FromInstance too
if you can't bind it directly to the Character type i think something like Container.Bind<Character>().FromResolveGetter<Employee>() would work?
Hi, I'm using unity ILPostProcessor to generate some code on compile. On question, when I have 2 processors, it it possible to define which one executes first? it looks like they're being executed according to the order in the hierarchy
It should be alphabetical. You can prepend a number in the assembly name to change its order.
so with games using the mono backend, if you want to distribute patched DLLs you can just overwrite the old DLLs, assuming you have a modular DLL structure and not updating constants (which need a recompilation of anything using them) but what about when using IL2CPP? I'm not sure what the actual out put is like or if it would work the same way
Thanks, I want to bind base parent Character, all its interfaces and Employee itself when the instance has Employee type. So, I can inject the employee instance as interfaces + Character + Employee in other components of the gameobject
public class ComponentA: MonoBehaviour{
[Inject]
private void Init(Employee employee){ //Employee instance (component)
}
}
public class ComponentB: MonoBehaviour{
[Inject]
private void Init(Character character){//Employee instance (component)
}
}
public class ComponentC: MonoBehaviour{
[Inject]
private void Init(IEntity entity){//Employee instance (component)
}
}
such a pity that Zenject is no longer being maintained 
And all because of Pokemon GO 😔
fixed?
Ye thank u
Which one do you choose? There is ItemDefinition scriptable object with a prefab. Now, I want to instantiate different prefabs in different situations related to this item. For example item in the storage, item on the ground, item in the character's hands, etc.
It is worth mentioning it is a 2d game.
I can change GameObject prefab to something like below
// ItemDefinition SO
public PrefabData[] Prefabs;
[Serializable]
public class PrefabData
{
public string Key;
public GameObject Prefab;
}
So, I can get the suitable prefab by key based on the situation.
Another way is to have only one prefab and then all item sprites in that prefab as child, then enable/disable them.
Which one do you prefer? and any better suggestion?
what are the keys for? if they're those situations, that's a code smell in my opinion. Why have PrefabData at all? if you have different prefabs for different situations, why not have ItemDefinition just have those prefabs directly? ItemDefinition.StoragePrefab, .GroundPrefab, .HeldPrefab etc
If the difference between those prefabs is clear, then I would probably prefer to have them separate for the sake of resource consumption. Some games, like VR or sandbox games, might prefer all instances of an item to be the fully featured version.
So I want to implement a system similar to Minecraft datapacks, where you can define certain content for the game in JSON and have it work automatically. Does unity have something like this already, and if so, how can I use it?
I could lift the code from the game engine I was making before this project, but I want to try to do it natively if possible
here's the setup for my question
- we know there is
SerializeReferencewhich can "serialize" interfaces - i can get this to work correctly when i have class implementing said interface
- is it possible to get this to work correctly if i have a scriptable object or monobehaviour implementing this interface?
actually i just learnt that serializereference tends to break if you rename classes
Use MovedFrom attribute to rename serialized reference.
If you want to use a ScriptableObject instead of C# object, you can simply create a wrapper class. If the idea is to use UnityEngine.Object with interface, you should look around for tool that support that. As far as I know, there is no support in engine. The idea, in most case, is to also create a Wrapper with Generic. I also believe that you can use implicit conversion to make it seamless.
Odin Serializer should cover you (not tested) or you could look into asset such as https://forum.unity.com/threads/free-serialize-interfaces.1145213/
Alternatively, you can remove the needs by using component instead of inheritance. In other words, instead of having something like IDamageable, you have a component Damageable. This is usually my preferred approach given that interface require you to reimplement most of the work and multi-inheritance is not supported.
from my searching, MovedFrom only works once
you can't chain it like FormerlySerializedAs
You only need to make it work once don't you ?
oh and i guess reserialize all the data once i do it
If I am correct, ReImport change the data.
the reason i'm shying away from this is because i didn't want to lock into a particular 'form' of data i suppose
Not sure though
for quality of code purposes
What do you mean ?
scriptable object is just a way to contain data
really i'm writing a class that takes, say a List<IFoo>
for the cases where this class needs to be serialized, i will always use some ScriptableObject implementing IFoo
Why ?
but i also use this class in script, where it should really just be a list of interfaces
You should always strive to have the lowest abstraction level possible.
the lowest abstraction level is IFoo
Not really, if it is not needed.
i do need it lol
Not from what I understood.
i'm writing code for what is essentially an Action<X>
so it operates as C# object
ok you know what this is quite complicated to explain
Not sure why you would need a scriptable object to implement something similar to an Action<X>.
the Action<X> contains a field List<IFoo>
I mean, usually Action are unique to each instance, they are not shared.
basically it boils down to being able to build Action<X> both in code and by deserialization
By example, if you have a Door, which have a "OpenAction", you would usually serialized it straight on the door itself.
But, obviously, I know little to nothing to what you are actually trying to do.
by Action<X> i really just mean a function that takes in X and has no return type
and actually it's really an Action<X, List<IFoo>> which is a function which takes in X and List<IFoo> and has no return type
but via currying you can reduce it to a Function<List<IFoo>, Action<X>> which is a function that takes in List<IFoo> and returns Action<X>
concretely i am writing an action that applies a status effect to a character
so X is Character and List<IFoo> is List<IStatusEffectFactory>
Why a factory ?
I mean, you need something like a factory, but why implement it directly
Really simple way of doing it is:
public class MyDebuffDefinition : DebuffDefinition
{
public class MyDebuff : Debuff
{
}
public Debuff Instantiate() {...}
}
i do have quite a complicated status effect system
You can pretty much implement everything with what I have shown you.
nevermind i think i'm not able to relay the intricacies of the system to you succinctly lol
You do you, but from experience, as little as I have, you never need to have a complicated level of abstraction.
It should come naturally, and by step.
i guess the upshot is that i can't just have the actual instances of these status effects floating around
there are fields in the status effects which can only be populated upon knowing which character the effect is on
The instantiate method is there for that.
nvm i have no clue what architecture you're suggesting me to use with this
Character attacks -> Ask Weapon if there is any weapon buff -> Instantiate Weapon Buff depending on the target hit.
wanting to abstract the application of this status effect as a serializable action is so that i can attach it onto various events, eg
- upon taking damage
- upon dealing damage
- upon killing
- etc etc
public class MyDebuffDefinition : DebuffDefinition, IUponTakingDamage
{
public class MyDebuff : Debuff
{
}
public Debuff Instantiate(Attacker attacker) {...}
}
and i mean there are other actions i wish to attach onto these events
nvm i dont think i have successfully conveyed what im trying to do
Feel free to try again whenever you want.
public class GiveCharacterStatusEffect : IAction<Character>
{
[SerializeField] // I cannot serialize arbitrary interfaces
private List<IStatusEffectFactory> statusEffects;
public void Invoke(Character character)
{
List<StatusEffect> toApply = statusEffects.ConvertAll(x => x.GetStatusEffect());
character.StatusEffectHandler.AddEffect(toApply);
}
}
the fix is really just to change IStatusEffectFactory to StatusEffectSOFactory, where StatusEffectSOFactory : ScriptableObject, IStatusEffectFactory
but this stops me from using this class purely in script
You either use Editor Tooling as I said earlier, or you use StatusEffectSOFactory like you did.
i mean what i can really do is
public class GiveCharacterStatusEffect<S> : IAction<Character> where S : IStatusEffectFactory
{
[SerializeField]
private List<S> statusEffects;
public void Invoke(Character character)
{
List<StatusEffect> toApply = statusEffects.ConvertAll(x => x.GetStatusEffect());
character.StatusEffectHandler.AddEffect(toApply);
}
}
public class GiveCharacterStatusEffect : GiveCharacterStatusEffect<StatusEffectSOFactory> {}
all this is just to get a serializable status effect factory, but as i said if i did SerializeReference then the serialized data is not resistant to refactors
Can you not restrict on a ScriptableObject and an Interace ?
no lol
I mean, you want to have the ability to use other type of object than ScriptableObject or not ?
Because, you either serialize UnityEngine.Object or POCO.
i mean yea as it stands this class is still a C# class
then i would proceed to have
class MonoAction<T, X> : MonoBehaviour, where X : IAction<T>
{
public X action;
}
class GiveCharacterStatusEffectMono : MonoAction<Character, GiveCharacterStatusEffect> { }
so i would then have many actions and then i'll use code generation to genereate these for each action
You could, by example, have your UnityObject be serialize through a wrapper. This would enable you to support ScriptableObject and non ScriptableObject reference.
public class GiveCharacterStatusEffect<S> : IAction<Character> where S : IStatusEffectFactory
{
[SerializeReference]
private List<S> statusEffects;
}
public class StatusEffectFactoryUnityReference : IStatusEffectFactory
{
}
yea i've basically been adopting this pattern where my C# object is serializable and my scriptable objects just wrap the C# object
so my problem now is that my C# object isnt always serializable
in this case this particular action isnt serializable unless i choose a particular representation for the statuseffectfactory, ie the scriptable object form
Anyway, my approach would be something like that.
public class BuffDefinition {}
public class BurnDebuffDefinition
{
}
public class Equipment
{
[SerializeReference]
public List<Effect> effects;
}
public class Effect {}
public class BuffEffect
{
[SerializeField]
private BuffDefinition buffDefinition;
}
public class Character {
public class Attack() {
...
ApplyAllAttackBuff(target);
}
public class ApplyAllAttackBuff(Target target)
{
var effects = Equipment.Get<BuffEffect >();
foreach(BuffEffect effect in effects)
effect.Apply(target);
}
}
yea this is what i did earlier in the project before i had to consider more complications
hence all the funny abstractions that eventually came about
It seem you are still trying to understand those complication.
Because I would ask what complication, but I am pretty sure you would have a hard time to say.
yea but basically each damage instance goes through a ridiculous amount of mutation before application
yea so for instance the equipment might not know what effects to apply
The function Get can be aware of the context.
If not, the function Apply could be joint with a function CanApply
i mean by not abstracting it into an action system it really becomes ridiculous to implement the other things
Effect is more than enough abstraction to be able to apply it with other system
like there can be arbitrarily many things that can occur
I ran into a funny design problem where I'd cache my buff effects (calculating damage/time) as soon as I equip the ability/equipment but eventually ran into an issue where I would recursively cache similar data if say I had some effect that proliferated between objects
Those things can be fix whenever they need to be fix.
i just brought up application of status effect as a particular case where the pattern doesnt work
solving this particular problem doesnt actually solve it for my general case
Ok, let's say we want a Quest to apply a Debuff.
no its not necessarily just applying debuffs
it could be literally any function that takes in Character
Ok, let's say we want the attack to be duplicate whenever the Character attacks
Would that be enough for you ?
as i said im really just looking for a clean serialization solution lol
I gave you earlier all the possible solution for serialization. There is no other as far as I know.
its not just Action that needs to be serialized correctly
Personally, I do not need any editor tooling as I use the pattern I have shown you and they are more than enough in all the case I faced. Which, some were complicated.
My solution to these type of events is just using enum comparison with delegates which were split by behaviors such as targeting.
and just check for them in code when doing damage, ect
Type casting with interface would probably better ?
Maybe? I'd just gone by my own design choice with it after trying a bunch of ideas.
I mean, the enum is basically the Type while the delegates is the interface method.
Having enum -> dictionary delegate lookup to trigger a behavior where I've kinda landed on
yea i just dont like how i need to compromise on code quality to make things work with unity
enums are also not resistant to refactors
Enums are usually an Obsessives Primitive violation.
it's unfortunate, but unity's editor tools are pretty lackluster. Either grab yourself some package like naughty attributes or odin.
and mackysoft's serialized references
As I said, you can implement Editor Tooling to reduce such restriction.
Thanks, I agree and in my view, the first one is more suitable as well. Defining an array of PrefabData
https://forum.unity.com/threads/serialized-interface-fields.1238785/
i found a thread discussing my problem lol
Problem
It is not possible to assign an interface-type field in the inspector. The field does not show up.
public interface ICharacterData { ... }...
What do you think? URP rendering pipeline and srp compatible shader
Batch count is huge but in the frame debugger, you can see it is low 29
Stats window is not reliable, especially on SRPs.
doesnt help with gpu instancing either
And, as I stated, you can solve the issue with either changing your approach (using SerializeReference + Wrapper) or by using Editor Tooling. In the thread you sent, there is multiple implementation of such tool.
Is unity suitable for world streaming(chunk loading/unloading)
or i should consider switching to unreal/smth else
If it is, where can I start from(some resources/videos) to learn how to do it
As far as I know, there is nothing build to "stream world" in Unity. The closest you can get is Additive Scene with Addressable.
Yeah, but you can always Instantiate() or GameObject.InstantiateAsync()
Or maybe it's possible to load the entire terrain grid and disable most of terrains
Somebody also mentioned having each chunk as a separate scene, but idk if loading/unloading the scene is not going to cause lag spikes
heya, im developing a snow deformation shader, and i'd like to add ray to mesh collision using a compute shader, but i heard those can be quite expensive, so is there any way to make it more efficient than just checking a bunch of ray collisions for each triangle of the mesh?
obviously a low poly mesh and bounding box are my first instinct, but what can i do if i have a deforming mesh?
also, all the rays are going straight up if that helps
For some of unity feature you need to have a scene. You can use Addressable to load resources, but you are going to have a spike for sure when the scene is initialized. I suggest dividing between static and dynamic environment or at least reducing the amount of script.
No, you do not want to do that. You want to utilize pooling.
Help, OnTransformChildrenChanged() isn't getting called in my code.
Does anyone have some idea wth is going on?
The code is basically:
void OnTransformChildrenChanged() {
refreshChildren();
OnStructureChanged();
}
and I am trying to use this even in editor component
more precisely when I drag a game object in hierarchy from one parent to another
this smells me like something Unity can't really do
or can it?
if you're testing it in edit mode, I assume you have decorated the script with ExecuteInEditMode or ExecuteAlways?
I decorated the method...
...so when I added it to class it now works
👍
thanks
although it seems like this event is triggered before children change, and not after
is there some way to get a list of children that changed? More precisely the new children
you might want to double-check since that's not the behavior I see
which Unity version are you on?
2022.3.29f1
hmm, I am 2022.3..32f1 so I doubt it's that
Just to be clear: we are talking about MonoBehavior, not UIToolkit or anything
yes
okay, thanks, that's the error on my part
it works as intended
I have filtered by the component type, but I add component only after reparenting
that's why it's not included
i mean objects have to at least be rendered when player is looking at them, and get physics shape when player is in neighboring chunk or smth
I have a Dynamic Music System where I can do stuff onBeat.
I have delaget which I can subscribe to, to do stuff on other script synced to my music.
The problem is, sometimes the event is happening twice (maybe in the same frame dont know) so I can for example switch around a bool or so.
Im starting a endless Couroutine when I initialize the Music System like so:
{
while (true)
{
yield return new WaitForSecondsRealtime((float)timeToNextBeat);
if(onBeat != null)
onBeat();
}
}
on a debug it often looks like this, onBeat is even worse then onBar.
I dont know how I can fix it or what I did wrong in the first place.
Keep in mind timeToNextBeat is double because its synced to the AudioSettings.dspTime to make it more accurate.
So basically what I want is a Event System that is framerate independend but because I want to do stuff that is not I did this. Any ideas?
A coroutine is frame rate dependent. In the sense that it's running at a specific time of the frame. It's not gonna follow your timings precisely, especially if they need to use a double for precision.
If you want to be completely independent from the main thread loop, you'll need to run your logic on a separate thread.
will not work, because it has to run on WebGL
so I need a solution to filter out second calls somehow.
Well, then you're out of options.
I know that the loop isnt following precisly but the second call is weird
Well, you can check the current frame and the last frame you performed the logic
but I dont need the visuals to follow the beat exactly
How exactly are you debugging it?
Are you sure that the 2 calls are executed on the same frame?
currently like this, dont be confused with the wrong naming and stuff, im in the "WTF is going on phase" 😄
nope I dont think they are
Print the frame number
how? 😄
And if they're not, then what is the problem?
I wonder if the wait for seconds param is 0, would it execute on the same frame or skip one?🤔
Then, there must be an issue with your logic. How exactly are you determining if it's "too soon"?
Or too close
haha that my stupid animation transition sometimes just skips back
I will record a short video
skip one
Yeah, that's what I remembered too. Just started doubting it a little bit.😅
wait for seconds 0 is the same as yield return null
hope this helps
I just use a animator bool parameter to switch between animations without a transition, goal is to have a transition in there.
The scale down thingys are also subscribed to the same event, but the script in there doesnt seem to bother lol
maybe this helps.
its Framecount and the timeToNextBar
Yes, and you should use pooling. By doing so, you will be able to reuse your object and not instantiate any of them, or only once.
how can i reuse the chunk
if each chunk terrain is unique
Idk if object pooling can help me by instantiating 10000k disabled terrains
and enabling/disabling them at runtime
definitely better than instantiating them on the flying and garbage collecting them, over and over.
do you mean 10000k terrain chunks?
if so, is that really all going to be visible to a player at once?
ofc not
then you definitely want to implement a form of pooling. Since this is for terrain, pooling might not even be the way. Usually when people do mesh-based terrain, they generate the chunks dynamically around the player as the player moves through the world (on the client) so, rather than pooling, the chunks are always there and just the height data and materials are updated.
so you'd have your LOD0 chunks nearest the player, then the LOD1 surrounding those, etc
and if its multiplayer, the server will operate completely different; either all the terrain will be loaded at LOD0 at all times or you would load up all relevant zones chunks that have players within them and unload ones that don't
Hi everyone,
Situation - I'm designing a construction tool which generates railway tracks procedurally (the same way Cities Skylines does for roads).
Issue - My concern is about limiting the cost of collision checks for intersections when preview is rendered, to prevent tracks from crossing each other when built. My curve is sampled over a quadratic Bézier, meshes are generated to connect each sample and are merged together using CombineInstances.
Thoughts - Where this issue would have been OK for only straight tracks, I'm wondering how to best design my architecture to handle curved tracks intersection efficiently. As they are roughly composed of ~40 consecutive straight segments, I'm not feeling like as many box colliders would do the job checking against all the already built segments (which could easily rise up to more than 10,000 box colliders).
My best bet is currently on Physics.OverlapBox() but I'd like to hear your opinion on the matter. Thank you.
Do your roads already require colliders for other purposes or are you only adding colliders to them for this purpose? If they're already there, it makes more sense to use them with physics queries. But if not, it might make more sense to make your own collision logic that is optimized for this problem.
Indeed^
And if you do that - I would recommend taking a similar approach to the physics system. Give each section of road an AABB (axis aligned bounding box) and use a QuadTree/OctTree or other spatial acceleration structure to do a very performant initial "broad phase" intersection check.
That will cull the potential candidates for a collision down tremendously. At that point you can use something like the math described here: https://stackoverflow.com/questions/4039229/checking-if-two-cubic-bézier-curves-intersect in order to check for the actual collision of two bezier curves, or maybe even just compare all the straight line sections in a relatively naive way.
@sage radish They don't need any collider except for this purpose. I think I've made up my mind and I'll use the track MeshRenderer bounds AABB to discard most tracks, and loop over each track segment within it checking for line intersection. That should be efficient enough 🤞
@sly grove I thought of implementing my own octree/BVH/whatever spatial partitioning but iirc Unity physics engine already implements theirs so I'd have preferred not to reinvent the wheel and take advantage of it. I guess I'll just benchmark with my solution above, I just ignore how well Unity physics engine partitions space dynamically as expanding bounds of such structure can be very quickly problematic.
well, seems like 10k terrains loaded are gonna kill ram
i made them relatively small(128x128)
it is for multiplayer, but for small amount of players, so more than 90% of the world is gonna be unloaded most of the time, and all AI there is gonna be simulated
Hey all, I'm trying to do something a bit unusual. I would like to compile a C# code from a string at editor time, and to do so I'm using the CSharpCodeProvider module. It's working nicely for basic script but I would like to give access to the UnityEngine namespace to my script, especially for the Vector3 type. I've something like this :
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateInMemory = true;
parameters.GenerateExecutable = false;
//This alone produce the error : The type `System.IFormattable' is defined in an assembly that is not referenced. Consider adding a reference to assembly `netstandard, Version=2.1.0.0,
parameters.ReferencedAssemblies.Add(typeof(UnityEngine.Vector3).Assembly.Location);
// So I tried to add this but then get this error for almost all possible type : The predefined type `System.Object' is defined multiple times. Using definition from `mscorlib.dll'
parameters.ReferencedAssemblies.Add(typeof(System.IFormattable).Assembly.Location);
string code = scriptPrefix + script + scriptPostfix;
CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);
As noted in the code sample, I don't understand the proper Assembly reference to pass to get it working. Does someone have an idea ?
can you first explain the motivation to compile the code manually?
what you are trying to do seems to me like a code smell
@hardy jacinth So we have an Editor Extension to generate animation curve with a graph editor, keyframe and more... and we would like to add a "simple" script editor that would allow to manipulate those curve to perform complex operation on them. It all happen on the editor side, so obviously we could simply create those expression in a C# file and have a workflow working with that, but that tools is intended for our animator so the goal is to have something a bit more streamlined and tightly integrated to the graph editor. I don't know If you know After Effect but the end goal is something similar to their expression engine based on Javascript.
For ease of development and generating the scripting API I wanted to make the expression engine evaluate C# code, that why I looked at the CSharpCodeProvider.
After some research I also found this unity asset : https://assetstore.unity.com/packages/tools/integration/roslyn-c-runtime-compiler-142753#description
Which is based on Roslyn that seems more robust and recent that CSharpCodeProvider. I Think i'll give it a shot to see if it's easier to implement.
Hmm, okay. I don't know the expression engine in after effects so I am not sure what kind of complicated expressions you have in mind here.
My thoughts for your case:
- if the tool is meant to be used in the ditor, then you shouldn't need roslyn-c-runtime-compiler. This tool is, as far as I can tell, meant to be used in runtime when the game is built
- using a C# language as a scripting language for curve editor seems like a massive overkill. You should instead consider the following:
- would the user of that tool be able to use it comfortably? An animator may not be a programmer, remember
- how extensive would the API for the scripts would have to be? Is the use case even realistic, or is it a set of 4/5 fixed functions that can be hardcoded and added on-demand by programmer when animator requests them?
- maybe you don't need a full blown scripting language, only a simple expression evaluation model defined with simple expressions?
- Are you sure you are trying to solve the right problem? Would implementing the solution otuside of unity be a better approach? Maybe you should focus on proposing to change the workflow instead? Something like rigging and animating in blender (blender has expression driven animations as well) and only exporting the animations and handling blending and event-driven animations in unity? I am simply
- what are "complex" operations? Try listing them and look at the problem from a broader perspective
- if you want to generate C# scripts you could simply write to
.csscripts in the unity and let IT handle the recompilation. No need to compile by hand if Unity can do that already. - possibly instead of writing scripts you could write a set of modular components that are fixed and composable, just like nodes in the ShaderGraph, and write an asset importer that builds a runtime model of an expression?
- Roslyn may be an overkill
- C# compiled expressions can be an alternative
- compiling by hand in unity is very risky
There are libraries designed for evaluation expressions with C# like syntax, such as:
https://github.com/codingseb/ExpressionEvaluator
I've been in a similar situation once. The request was to write a tool that would help with rendering textures of models imported and positioned in unity. The artist's workflow looked somewhat like this:
- They created a model, textures etc. in Blender
- They imported everything to unity
- They applied a skeleton and one of the fixed poses to the models (with some small adjustments if needed) and rendered it on a transparent background to create fixed textures
The request was to improve the process, because they have been using the tool written previously in unity and had to manually click on "render" in the editor tool for each model and the whole process was tedious. A "batch" tool was proposed, while the ideal workflow would be to... simply skip importing into unity all together and handle that in the modelling software...
Maybe I am wrong because I don't see a broader picture for your case, so maybe some concrete examples of what those "advanced operations" on generated curves look like could help me to understand? Perhaps some screenshots of what your curve tool looks like?
@hardy jacinth Wow, that's a detailed answer. Thanks a lot for that. Yeah I guess it's completely overkill to use C# for a scripting language no doubt. Among your proposition there are 2 that I'll definitively investigate more :
- Writing to a .cs file and let unity handle the recompilation
- Using modular component to make a node based graph, that seems interesting.
So those operation are mostly math / physic. For example I could have 2 curve drawn by hand representing the Amplitude and the Frequency of a Sinus and therefore I need an expression to compute the value of the Sinus at a time t, given the amplitude and frequency at that time. Or it could be a hand drawn curve of a Vector3 and the need to compute the Rotation around that vector based on the angular velocity defined by another hand drawn curve. But it could go all the way to I don't know, generating the wave function of a ripple on a water surface. This is not for gaming development, it's more related to physics research and R&D, it's about generating signal to control Realtime electronics and device with Realtime sensor monitoring.
But you gave me good lead on how to tackle this problem, I'll think about how to approach it a bit more.
@sage radish Thanks, I'll take a look at that.
Hey all ,
When I try to serialize and deserialize a normal scriptable object with newtonsoft.json, it throws a warning saying that it cannot be created with scriptable object new() creation.
I made a custom so converter to solve this, but while it doesn't give an error in normal default converter, I get an error like this in custom converter:
Self referencing loop detected with type 'GP.Serialization.DataTypes.GPGraphData'. Path ''' .
In order not to get this type of error, for example vector2 and vector2.normalized were causing the same problem, but I solved it with custom implementation, what is the reason why this is happening now?
public class GPSOConverter<T> : JsonConverter where T : ScriptableObject
{
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
T tempObject = ScriptableObject.CreateInstance<T>();
serializer.Populate(reader, tempObject);
return tempObject;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
Hello devs, I'm looking for a way to generate NavMesh at runtime through multiple threads or any way that could reduve performances. We're currentily making a game where we procedurally generate flying islands with a chunck system but we have issue with generating the navmesh for ai to stand on because we regenerate navmesh each time a player leaves a chunck to another one.
We are using Unity 2022.3.16 and Unity new nav mesh surface system to generate navmesh at runtime.
If there's no way to use multi thread operation, will there be a way to aproximate a first navmesh with less precision and then, when said, update this navmesh ?
You could look into: NavMeshBuilder.UpdateNavMeshDataAsync. Never used it but a quick google search seem to point towards that.
Mmh gonna check that
i cant make a fluid sim to work properly
i need it for the engine
try this ```// Update method
void Update()
{
for (int i = 1; i <= nx; i++) // Corrected loop bounds
{
// Flux calculations and updates
}
// Update ghost cells
density_new[0] = density[1]; // Reflective boundary conditions
density_new[nx + 1] = density[nx];
momentum_new[0] = momentum[1];
momentum_new[nx + 1] = momentum[nx];
energy_new[0] = energy[1];
energy_new[nx + 1] = energy[nx];
// Copy values back to original arrays
Array.Copy(density_new, density, nx + 2); // Corrected array length
Array.Copy(momentum_new, momentum, nx + 2);
Array.Copy(energy_new, energy, nx + 2);
}
Anyone here have experience with making physical items?
I've created a very rudamentary system by setting velocity to go straight to the hand. It works, but it's kinda shit
rb.linearVelocity = (targetPosition - grabPoint.position) / Time.deltaTime;
(targetRotation * Quaternion.Inverse(grabPoint.rotation)).ToAngleAxis(out float angle, out Vector3 axis);
rb.angularVelocity = angle * Mathf.Deg2Rad * axis.normalized / Time.deltaTime;```
What's the next step to making this better?
Is that in a fixed update?
Is this from chatgpt?
I had a friend over here earlier and he made the suggestions
he was looking over my shoulder as i was asking about my own questions with my game, he knows a few coding languages but nothing about unity
if it doesnt work sorry, if it does i will let him know lol
It is against the rules to provide ai generated code as answers, or ask for help with it here
i looked up chatgbt... seems like its for story telling
my menu doesn't want to show up someone helps me
code from AI would only make me more c-onffused
its quite clear you're using AI, i could tell from the other channel. Please stop lying and grow up.
my menu doesn't want to show up someone helps me
this is a coding channel, id:browse
FDDS
my menu doesn't want to show up someone helps me
actually I followed the 15 part series from mercenary camp on you tube to make the chess game
with unity jobs is it bad to use them every frame ? would that be performance heavy since i presume jobs have to create threads and dispose all the time ?
are they best just for big processing jobs every so often
my menu doesn't want to show up someone helps me
i have to apply a lot of TRS matrices to my data so want to do it in parallel
my menu doesn't want to show up someone helps me
<@&502884371011731486> spamming
SORRY
!mute 1130192242787758142 30m do not spam
kzodeasg was muted.
This is absolutely not an advanced (nor code?) issue regardless
From my understanding:
.Runis just calling the compiled code, there should be basically no extra overhead.- Unity internally manages worker threads, and
.Schedulesimply schedules those jobs and have them eventually dispatched to worker threads to run, so the overhead is probably also minimal.
so they are probably pooling and reusing the jobs then ?
In my game I have something that does job.Schedule(...).Complete() every frame and it works fine.
have you checked profiler, does it not create heap when it makes the worker threads? one would assume it would
Basically yes, it's not spinning up new threads every time you schedule a job, it just puts those jobs into a queue and existing worker threads will pick them up once available.
ah i see
are you also creating and disposing native arrays every frame or using a persistant and reusing it
Reuse wherever possible for sure.
see the docs says persistant native arrays add perf cost
so i assumed temp ones were better
The entire job struct is only created once at the start and just keep rerunning it.
IIRC that part is basically saying "allocating a persistent container is slower than allocating a temp"
But if you are only allocating once then it's irrelevant, "slower allocation at start up, and never need to allocate again per frame" is still way better than "faster allocation but have to do it every frame."
well the docs says Don't use Persistent where performance is essential.
so i dunno how to interpret that 😄
When in doubt, profile it.
true
At least the last time I profiled "persistent allocator + reuse" vs "temp allocator but reallocating every time" the former vastly outperforms.
this isn't what you asked, but keep in mind when using any type of multithreading: if two cores access the same cache line, the cache line becomes invalidated and the data needs to be pulled from the DRAM again. which is a massive penalty assuming your stuff is still hot in the CPU cache.
you said you're working with matrices, so you might want to look into some sort of AVX/SIMD type stuff if you really want to go full turbo mode
pretty sure burst uses SIMD with its matrices from the unity math api anyway
so i shouldn't need to worry about that
or am i wrong on that?
no clue. typically SIMD operates on massive batches of data rather than one time calls
I've never done SIMD on matrices so I could be totally wrong here
the performance you can get from proper SIMD totally blows multithreading out of the water though. it's just a real pain in the ass to do
I've never looked into it, but supposedly Burst compiler which uses LLVM under the hood, does auto vectorization. So code like for (var i = 0; i < length; i++) { /* do stuff with data[i] */ } should get auto vectorized and turn into SIMD, at least for the stuffs compiler can recognize.
the same thing is going to happen
sorry to hear that. Its way above my knowledge level
ik, i could see you used ai to try to help me
thats what somebody thought, but it wasnt... what are you trying to do? from what i read your trying to calculate gas law for some reason?
isnt there online stuff for that already?
It will make engine run and i could use the same fluid sim to also create sound
Yes and no
There is one person that made it, but he will not share it
if you want to add me as a friend, you share more about it... I can email it to my friend and see if he gets back to me
he knows nothing about engines tho, just math and coding
Anyone know how to generate lightmap UV's for ProBuilder via c# ?
does not look like you can. Did you just for curiosity check the script and what the editor button is doing if you can? My answer is based on https://docs.unity3d.com/Packages/com.unity.probuilder@4.0/api/UnityEngine.ProBuilder.ProBuilderMesh.html#methods
My project uses URP rendering. My question is although it is URP but my custom frag shader (CG) is OK! It works.
Can URP projects work with CG shaders?!
Not as far as I know
I have checked. In the graphics setting, urp asset has been assigned!
Other urp shaders work as well
What about quality settings?
Good question. Maybe they contain both CG and hlsl code? The compiler would only compiled what it cares about.
Or you're misunderstanding something. A confirmation error.
Also, shader graph supports both urp and built-in nowadays, if you're assuming based on that.
CG shaders are just HLSL shaders with some automatically included files to add compatibility with CG, like the fixed type.
I know. My problem is about something else
For example, there are two shaders.One of them contains hlsl with hlsl files
SubShader
{
Tags {"Queue" = "Transparent" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" }
Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha
Cull Off
ZWrite Off
Pass
{
Tags { "LightMode" = "Universal2D" }
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
The other one
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
Both of them have been used in the scene and prefab and they work
Unlit shaders from built-in RP work because they don't have an invalid LightMode tag and aren't doing anything incompatible with URP.
Lit shaders from the built-in RP only become pink in URP because URP is filtering out shaders with incompatible LightMode tags. They could technically render, they just wouldn't render correctly.
Perfect, thanks, appreciated dude.
So, I can use custom built-in shaders unlit shaders
This is in fixed update
One of the issues is that the character uses CC, and whenever it moves the held object lags behind terribly and jitters
I can't imagine how you can fix that. It's kinda just a disparity between the update loops
That's really about it. I would be satisfied with just fixing that for this project, I'm not looking for anything fancy
Hi any one know how to setup Google Login? I followed the Documentaion nothing works
Where is your code, what did you try so far. whats the errors you get? Nothing works is no info at all
Do you get any prompt to login?
I got it once when run app first time and now I do not get it from my device
did you login back then? Or probably denied the access?
I would delete the app and install again to see if it triggers once more
I delete it many times I got loginned after first build all rest builds is not logining
delete app data also is not helping
What does Social.Active give you when logged?
Looks like the problem it cannot login to google via this line Social.localUser.Authenticate(OnGoogleLogin);
Google has different results on that topic. https://github.com/playgameservices/play-games-plugin-for-unity/issues/2620 and https://github.com/playgameservices/play-games-plugin-for-unity/issues/2425
No but are you using binary serialization instead of text?
anyway git revert/git checkout should sort you out
yeah, I fixed it with that 😅
I am using text serialization... but maybe the flag flipped?
Hi all, I have a "controller" class that acts as a proxy for other classes to request things like RequestEndRoom() & RequestRestartRoom()
However, I only want specific classes to be able to call these public methods. Is there some sort of design paradigm I can use to implement that access restriction?
I am considering using some sort of unique ID authorization secret that is present on those classes and feeds it to the proxy, which will authorize it
Appreciate any point in the right direction!
only let the authorized classes know about the controller, then. If you made it in a singleton, you have a code smell you're about to double down on with the weird authorization thing
is this for a multiplayer game where only the host is allowed to do these actions?
no, singleplayer
It's currently in a singleton that's too big to refactor right now
if you don't have time to do it right, when will you have time to do it again?
it sounds like you're trying to create something like C++'s friend
If you need to keep the giant singleton, just document that these methods aren't meant to be called willy-nilly
but that's kind of true for all methods
fair, thanks for the response!
I've bumped into a similar problem before -- I was trying to limit access to class Foo by handing our an intermediate Bar that held a reference to it
i also didn't want anyone to be able to construct a Bar on their own for reasons I forget
I wound up just ditching that
Hello, I have a quick question - do global properties break GPU instancing? I.e if I want to use a global property (set by Shader.SetGlobalVector(name)), do I have to use UNITY_ACCESS_INSTANCED_PROP and UNITY_DEFINE_INSTANCED_PROP?
And one more, when is the value of build-in shader props set? I need to override _Time so we can get more determinism from tests, and overriding it in Update didn't work. Is it even possible, or am I out of luck?
private void CheckWallCollision(Vector3 newPos)
{
if (IsColliding(newPos))
{
Vector3 adjustPos = AdjustCollisionPosition(newPos);
transform.position = new Vector3(adjustPos.x, transform.position.y, adjustPos.z);
}
else
{
transform.position = new Vector3(newPos.x, transform.position.y, newPos.z);
}
}
private bool IsColliding(Vector3 targetPos)
{
Vector3 start = transform.position + Vector3.up * (_capsuleHeight / 2 - _capsuleRadius);
Vector3 end = transform.position + Vector3.down * (_capsuleHeight / 2 - _capsuleRadius);
//Vector3 direction = targetPos - transform.position;
//float distance = direction.magnitude;
return Physics.CheckCapsule(start, end, _capsuleRadius, _collisionMask);
}
private Vector3 AdjustCollisionPosition(Vector3 targetPos)
{
Vector3 beforeTP = targetPos;
Vector3 start = transform.position + Vector3.up * (_capsuleHeight / 2 - _capsuleRadius);
Vector3 end = transform.position + Vector3.down * (_capsuleHeight / 2 - _capsuleRadius);
Vector3 direction = targetPos - transform.position;
float distance = direction.magnitude;
RaycastHit hit = new RaycastHit();
if(Physics.CapsuleCast(start, end, _capsuleRadius - Physics.defaultContactOffset, direction, out hit, 0.1f /*_collisionMask*/))
{
targetPos = hit.point - direction.normalized * _capsuleRadius;
Debug.Log("Wall has been hit");
}
Debug.Log(
$"\n {beforeTP} <- Where player wants to go : Where player will be going -> {targetPos}\n"
+ $"{start}, {end}, {direction}, {distance}");
return targetPos;
}
I am trying to make a CapsuleCast detect walls.
Sadly enough the
if(Physics.CapsuleCast(start, end, _capsuleRadius - Physics.defaultContactOffset, direction, out hit, 0.1f /*_collisionMask*/))
{
targetPos = hit.point - direction.normalized * _capsuleRadius;
Debug.Log("Wall has been hit");
}
Has none of it and doesn't want to detect any type of wall or config I tried to apply to it
I have read the Unity Manual (please don't post it here) and I am aware that a Capsule Cast won't detect a collision when it is already overlapping something...
But it doesn't overlap anything as there are one 3 colliders in my world and all have a different mask.
What am I not seeing?
You are not seeing the same that we are not seeing. Any debugging of the values involved
Distance is zero ?
Okay ... nope ... its still broken.
When I head to the wall and get in between the highest and the second lowest it works but when running into the highest wall .... it doesn't work
distance is the position I want the character to move to during input - the position its already at.
Meaning that when the player isn't moving the distance will be 0, that is possible right?
Direction is also zero, that can't be what you want
I'll test again
This is just forward movement.
What I find mostly strange is that the capsule collider does get triggered when coming in from the corner of the wall it seems...
This is where collision is detected
Im guessing there is something flawed in your logic
between these two.
The initial conditions are relatively the same but the results are different
at a guess targetpos is incorrect
private void HandleMovement()
{
_velocity += Physics.gravity.y * _gravityScale * Time.fixedDeltaTime;
CheckGroundCollision();
if (Input.GetKeyDown(KeyCode.Space)) Jump();
int horizontal = (int)Input.GetAxisRaw("Horizontal");
int depth = (int)Input.GetAxisRaw("Vertical");
Vector2 movement = new Vector2(horizontal, depth).normalized;
Vector3 nextPosition = transform.position + new Vector3(movement.x, 0, movement.y) * _runSpeed * Time.fixedDeltaTime;
CheckWallCollision(nextPosition);
transform.Translate(Vector3.up * _velocity * Time.fixedDeltaTime);
HandlePlayerGFXFlip(horizontal);
}
This is where "targetPos" is made but called nextPosition
Okay breakthrough
private bool IsColliding(Vector3 targetPos)
{
Vector3 start = targetPos + Vector3.up * (_capsuleHeight / 2 - _capsuleRadius);
Vector3 end = targetPos + Vector3.down * (_capsuleHeight / 2 - _capsuleRadius);
return Physics.CheckCapsule(start, end, _capsuleRadius, _collisionMask);
}
I forgot to actually use the thing .... targetPos during my collision check
Now I only need to figure out how I can prevent my character from clipping into a wall
when moving diagonally
how do i work with int[,] in a compute shader?
Probably need to put it into a computebuffer and do some index conversions in the shader so you can treat it as two dimensional
one sec, i'll explain better
i actually don't need int, bool is better, as i think rn
so, i need to create a bool array inside the compute shader with size(for example) 95x95
then i need to read it from script and loop like this
for (int i = 0; i < 95; i++) {
for (int j = 0; j < 95; j++) {
if (myBoolArray[i,j]) {
// do my code
} else {
// do my other code
}
}
}```
You have a jagged array there, not a multidimensional one.
I don't think you can have a StructuredBuffer<bool> so you'd have to treat them as integers
And you have to convert 2D into 1D array/buffer
is there a way to do that so i don't mess up indexing
computeShader.Dispatch(/**/);
computeBuffer.SetData(boolArray);
for (int i = 0; i <= 95; i++)
{
for (int j = 0; j <= 95; j++)
{
if (myBoolArray[i,j]) {}
}
}```
that's what i currently have, but compute shader part is empty
actually... i can just use 1d array with amount of elements = x * y;
and then inside the loop split it back to 2 number i need
if element index is bigger than x i add 1 to y and go ahead
sounds kinda stupid
i don't think i know what i'm doing
Well you can convert 1D to 2D coordinates something like thiscs int x = index % xSize; int y = index / xSize
will i be able to read it into a bool[,] array which is in my c# script?
or i should go for 1d in both computeshader and c# script
I think that's up to you
If you need to write into the buffer from the shader, you need RWStructuredBuffer, not StructuredBuffer
But where does the data in the buffer come from?
I thought you pass it from C#
What's the point of reading it back if it's not going to change inside the shader, is my point
buffer has fixed size and is repopulated with true/false's each Dispatch()
i don't pass related stuff to shader, only read from it
So the shader does write to the buffer?
yeah
Ok here you said you don't need it so just making it clear
wait
private ComputeBuffer buffer = new ComputeBuffer(95 * 95, sizeof(bool));
private bool[] cells = new bool[95 * 95];```
i create the buffer, then
computeShader.SetBuffer(kernelId, "cellBuffer", buffer);
then each frame i dispatch the compute shader
and then buffer.SetData(cells);
and after gathering data i loop
for (int i = 0; i <= 95 * 95; i++)
{
int x = i % 95;
int z = i / 95;
if (cells[i]) {}
}```
Careful, sizeof(bool) returns 1 in C#, as bools in C# are 1 byte, but in HLSL, they are 4 bytes.
You also need to change the array element type to be 4 bytes.
HLSL doesn't have any types less than 4 bytes, except in some special cases.
Change it into an int array, that's 4 bytes.
so in computeshader i also use int instead of bool?
RWStructuredBuffer<bool> cells;
or it's gonna work anyway
Up to you. I would use int just to make it less confusing.
hlsl sucks xD
If you want to save memory, you can use a RWByteAddressBuffer. Then you can even go as far as storing 1 bit per bool, with some bitwise operations in the shader.
computeShader.Dispatch(kernelId, Mathf.CeilToInt(95 * 95 / 16), 1, 1);```
mafs
lez go
Because the basic unit of operation on a GPU is a 4-component vector. That's why GPUs are fast — they can do in one cycle what takes 40 on a CPU. So on GPU you can for example add two 4-component vectors just as if you did one operation, essentially performing computation for free.
int x = id % 95;
int z = id / 95;
float3 coords = float3(x * 64 + 32, 1, z * 64 + 32);
float4 CameraDistances0 = float4(
dot(frustumPlanes[0].xyz, coords) + frustumPlanes[0].w,
dot(frustumPlanes[1].xyz, coords) + frustumPlanes[1].w,
dot(frustumPlanes[2].xyz, coords) + frustumPlanes[2].w,
dot(frustumPlanes[3].xyz, coords) + frustumPlanes[3].w
);
float4 CameraDistances1 = float4(
dot(frustumPlanes[4].xyz, coords) + frustumPlanes[4].w,
dot(frustumPlanes[5].xyz, coords) + frustumPlanes[5].w,
0.0f,
0.0f
);
if (all(CameraDistances0 >= -2) && all(CameraDistances1 >= -2))
{
cellBuffer[id] = 1;
}
else
{
cellBuffer[id] = 0;
}```
am i dumb
it always returns 0
first coord should be 32/1/32 cuz id = 0, which means x = 0 and z = 0
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(cam);
float[] planeNormals = new float[planes.Length * 4];
for (int i = 0; i < planes.Length; i++)
{
planeNormals[i * 4 + 0] = planes[i].normal.x;
planeNormals[i * 4 + 1] = planes[i].normal.y;
planeNormals[i * 4 + 2] = planes[i].normal.z;
planeNormals[i * 4 + 3] = planes[i].distance;
}
computeShader.SetFloats("frustumPlanes", planeNormals);```
that's how i pass planes
probably or maybe notall(CameraDistances0 >= -2) is not doing what you think it is
i have the same thing in another shader tho
maybe first try checking any() for cameraDistances0 only and see if that even works
or rather try to stop succesively and see on which stage it breaks
i just
i % 2 == 0
🙂
gonna have chess now ig
well
it's definitely not the shader error
buffer.SetData(viewedCells);
it returns a set of 0's
RWStructuredBuffer<int> cellBuffer;
in the method i just do cellBuffer[id] = 1; rn
then reading data and debug log every value
and it's all 0
do you have proper #pragma target maybe?
i only have #pragma kernel
what is target
i don't think it should matter since my other compute shader works well without target
different compute models support different types, so I had an idea that maybe by default in your case RWStructuredBuffer is not supported. iirc default compute model is 3.0 or so
it is supported for my other grass compute shader
#pragma kernel CSMain
RWStructuredBuffer<float3> positions;
and shader models are defined, idk, somewhere in HLSL docs: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/overviews-direct3d-11-hlsl
#pragma target 5.0 is what i go for ig
nah, still zeros
i can, but is int so bad?
actually why do i need float4
just float seems alr
dunno, from what I know shader compiler bugs are discovared on a daily basis, wouldn't be weird if there was an aundocumented edge case xd
cuz vector is the most universal, basic data type
wait
maybe when you defined RWStructuredBuffer<int> it's 4 times smaller than <int4> and <float4> so you index out of bounds
can RWStructuredBuffer<int> be read to int[]
unsure
i don't get errors for out of bounds
at least in c#
might be a shader error yeah
what do i put instead of int[] if i go for float4?
idk if you would get error in shader, it can depend, shader you even happily try to read and write garbage, in this term it's pretty similar to C++ and C
Vector4?
btw I don't really know compute shaders and their API but I did some regular shader shennanigans, but in your case I'm just throwing ideas
private int[] viewedCells = new int[16 * 16];
private ComputeBuffer buffer;
[SerializeField] ComputeShader computeShader;
private int kernelId = 0;
private Camera cam;
private void Start()
{
cam = Camera.main;
buffer = new ComputeBuffer(16 * 16, 4, ComputeBufferType.Structured);
kernelId = computeShader.FindKernel("CSMain");
computeShader.SetBuffer(kernelId, "cellBuffer", buffer);
player.SetActive(true);
}
public void UpdateVisibility()
{
computeShader.SetFloats("camPosition", cam.transform.position.x, cam.transform.position.y, cam.transform.position.z);
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(cam);
float[] planeNormals = new float[planes.Length * 4];
for (int i = 0; i < planes.Length; i++)
{
planeNormals[i * 4 + 0] = planes[i].normal.x;
planeNormals[i * 4 + 1] = planes[i].normal.y;
planeNormals[i * 4 + 2] = planes[i].normal.z;
planeNormals[i * 4 + 3] = planes[i].distance;
}
computeShader.SetFloats("frustumPlanes", planeNormals);
computeShader.Dispatch(kernelId, Mathf.CeilToInt(16 * 16 / 16), 1, 1);
buffer.SetData(viewedCells);
for (int i = 0; i <= 16 * 16 - 1; i++)
{
int x = i % 16;
int z = i / 16;
Debug.Log(viewedCells[i]);
}
}```
#pragma kernel CSMain
RWStructuredBuffer<int> cellBuffer;
float4 frustumPlanes[6];
float3 camPosition;
[numthreads(16, 1, 1)]
void CSMain(uint id : SV_DispatchThreadID)
{
int x = id % 16;
int z = id / 16;
float3 coords = float3(x * 64 + 32, 1, z * 64 + 32);
float4 CameraDistances0 = float4(
dot(frustumPlanes[0].xyz, coords) + frustumPlanes[0].w,
dot(frustumPlanes[1].xyz, coords) + frustumPlanes[1].w,
dot(frustumPlanes[2].xyz, coords) + frustumPlanes[2].w,
dot(frustumPlanes[3].xyz, coords) + frustumPlanes[3].w
);
float4 CameraDistances1 = float4(
dot(frustumPlanes[4].xyz, coords) + frustumPlanes[4].w,
dot(frustumPlanes[5].xyz, coords) + frustumPlanes[5].w,
0.0f,
0.0f
);
if (all(CameraDistances0 >= -2) && all(CameraDistances1 >= -2))
{
cellBuffer[id] = 1;
}
else
{
cellBuffer[id] = 0;
}
}```
16*16 everywhere is temporary
currently shader is just
#pragma kernel CSMain
RWStructuredBuffer<int> cellBuffer;
float4 frustumPlanes[6];
float3 camPosition;
[numthreads(16, 1, 1)]
void CSMain(uint id : SV_DispatchThreadID)
{
cellBuffer[id] = 1;
}```
emmm, are you testing it in editor or runtime? Start doesn't run after domain reload just FYI
Move the code from start to UpdateVisibily just before you do all your shader shennanigans, see if it helps
You are calling buffer.SetData after dispatching? 🤔
lol
one freaking letter
lez go it works
i spent an hour on fixing one letter
fps from 5 to 75 ez
now i have terrain culling xD
i need to rewrite culling a bit, but it's already cool
on target world size fps is still too low
i need some other way to manipulate terrains
Are they unity terrains or custom?
unity terrains
And what exactly do you mean with manipulate
since i thought unity terrains are cool
in games like skyrim you can see the entire world each frame
it's LODded as hell, but terrains are not billboards, you can easily see they are meshes
so my initial idea was to load every chunk/cell and test the performance
fps was less than 5
even tho unity tries it's best to downscale terrain meshes
then i decided to try culling terrains which are not seen by disabling terrain component
i wrote this cool compute shader which allowed me to have 120 fps on world size 16x16(each chunk is 64x64, so total world size is 1024x1024)
but if i scale it to have beautiful distant mountains far away, fps gets to like 20
rn world is nearly skyrim size(36,9km^2 compared to 37,7km^2 in skyrim)
and well, most of terrains are actually culled
but they are still 9k+ individual objects with scripts attached, and also with child gameobjects(grey cubes), which represent houses/castles/rocks on each cell
right now i have no clue what to do
is there a way to build just a single terrain out of those small cells or at least using all 9k heightmaps
and if it's possible, how do i make LOD for it
Unity already does LOD'ing for terrains
Maybe look at the settings here - at least Pixel Error, Minimum Detail Limit and Maximum Complexity limit should be relevant to it
https://docs.unity3d.com/Manual/terrain-OtherSettings.html
I'm not too familiar with those though - I ended up making my own terrain system that uses compute shaders for generation and a custom lod system
so if terrain is big, some parts of it get LOD'ded but near the player this terrain looks normal?
already played with those params on my chunks, but results are meh
You can turn on Shaded Wireframe in the scene view to see how the terrain LODs work
oh i see yeah
terrain lods itself based on distance to the player
well, that means i now need to find a way to create one terrain out of several small ones
MVP Architecture Enforcement : Use Assemblies or Just Use Namespaces ?
me chasing the school bus with toast in my mouth
Hey guys, I'm having an issue where fields marked as [SerializeField] of a specific type (ItemPresenter) don't show any class in the picker, even though there are instances of this type in the scene. I've verified everything I possibly could, but nothing seems to work. I suspect there might be some corrupted data because this issue started after a branch merge. Any ideas on what might be causing this?
What I've already done:
- Checked if the class and file names are correct
- Reimported the project (initially thought the issue might be related to my machine, not the repo)
- Reimported the library (same reason as above)
- Regenerated meta files for ItemPresenter.cs and the root prefab, just in case
- Compared the scenes between working and non-working commits
The picker for this component doesn't show any classes, nor do I can drag and drop directly either.
The picker isn't going to show "classes"
It will show assets of that type, if any exist
is ItemPresenter a MonoBehaviour?
Of course, I meant that 🙏
yup, it's a MonoBehaviour. This is old reference which is still present and works correctly - but now, after the merge which was like 2 weeks ago, i just can't change it
What object is Harbor Behaviour attached to and where is the Itempresenter you're trying to reference?
-Harbor (ItemPresenter) - prefab root
--BehaviourRoot (gameobject) - HarborBehaviour
--Misc (rest of the prefab hierarchy)
It's irevelant as it's not code related issue - I know it's working etc. But you have a good point, because in this case i can change the reference inside the prefab, but I cannot do the same when I'm on the gameplay scene
There are bunch of items already setuped on the scene, and they are just not picked-up by the select picker window. But if the context (scene stage) changes to the prefab stage, it's working correclty. That's weird 
right well I'm trying to figure out if you're trying to get a prefab to reference an asset in a scene
because that's not possible
not at edit time anyway
yeah sure, I could've probably better phrase that. Just for context I'm not a begginer I know how things are working - just in this case there must be some corrupted data which is causing the issue with the picker window and I can't figure it out
I've checked the scene diff, but I might do it again as in prefab stage everything seems to work fine
And as I mentioned there are already some hard referenced item presenters which persisted in those prefabs yamls
Update.. it's broken even for other types likes basic Transform.. but not all of them. Some objects are detected correctly
t:Transform
it's a filter, it would not do anything when the list is empty
It started working.. for no reason. I just iterate over different pickers to check which were working and then.. it just started work.
// Edit: Odin Inspector has a bug and version 3.3.1.3 fixed this
Hello, anyone has experience in implementing Google Tag Manager in Unity for Mobile platforms? I have followed a single one tutorial that i found, but with no success. (I dont know if this is the right place do ask this)
I need help with saving my data. My game's architecture relies on lists of Scriptable Objects with lists of integers in them. I am trying to convert them into JSON, but all I'm getting is their reference IDs. The list I'm displaying here, for example, is a list of object states in their scenes. Each of these objects is holding a list of objects with integers in them, but the only thing being saved is their IDs. Will the data be saved and loaded properly with nothing but the references? If not, what should I do?
This isnt really advanced. You should show how you're actually saving, it matters if you're using like json.net or json utility.
Also what object are you actually saving? Usually you should create some class which holds only the data you want to save, and then your SO can also have a field for that new class.
That's how JSONUtility serializes UnityEngine objects.
You should capture all your save data in POCO DTOs
Or use a different serializer
I'm using JSONUtility.
Maybe use Newtonsoft JSON. I use it and it works pretty good for converting things. Plus it works with pretty much anything serializable.
Json.NET is a popular high-performance JSON framework for .NET
I think thats the one I use.
Thanks. I might check it out. I've kind of already figured out how to make it work.
Alright! Good luck coding!
Ok so stumbled upon an issue. Everything was working fine, assed a couple items from assets that where already in the project from before. Now even with Networking disabled just placing a character in the scene it acts very wierd. I included a video here.
https://youtu.be/HXMrWUjrSSo
Anyone ever seen this issue before?
This is the issue Im having right now. Using Unities Starter Assests, the new input system. I have turned off the aimcamera and the aimscript and even turned off the Network Manager object and scripts.
It was Odin Inspector causing this on version 3.3.1.2. On version later it's working correctly
Hey lads! Does anyone here have a working GPS-system/script for android/IOS? Can't get mine to update the location of the device :/
Guys, Can DXC shader compiler be used in Unity?
Unity has it available in package manager
Right? Can someone confirm or deny, I decided to check and cant find it XD I remember getting it there...
Maybe it's installed manually "com.unity.nuget.newtonsoft-json": "3.0.2"
at runtime?
In any ways 🙂
Maybe.
well unity compiles HLSL for you during the build, what else do you need it to do?
I'm trying to display my custom serializable class in the inspector and it's not working
[Serializable]
public abstract class ShaderPreset {
protected abstract RaymarchingShaderGenerator CreateProcessorForScene(SdfScene scene);
public string MainShaderForScene(SdfScene scene) => CreateProcessorForScene(scene).MainShader();
}
[Serializable]
public class BirpShaderPreset : ShaderPreset {
public ShaderInclude[] additionalIncludes;
public string[] additionalDefines;
protected override RaymarchingShaderGenerator CreateProcessorForScene(SdfScene scene) => new BuiltInGenerator(scene);
}
I added a public ShaderPreset preset = new BirpShaderPreset() field in another class and it doesn't display
I expected a foldout with 2 fields, one for shader include assets and another one for strings to display
i don't know why it's not displaying at all but it's a ScriptableObject so it'll be an object reference field, make it a plain C# class if you want it to be serialized inline
ScriptableObjects don't need to have [Serializable] either
oh, sorry, I have modified code since, disregard the scriptable object, I am editing the message to reflect how I would like it to look like
it's a plain C# object
ahh in that case polymorphism and unity serialization aren't really compatible, you need to specify the concrete type for the field
it'll be serialized as whatever the type of the field is, and since it's abstract you can't serialize that
oh no
isn't there any workaround?
I already have a custom inspector for the type, so If I could even write a generic code just to handle the abstract base class
it needs to be serialized indirectly for polymorphism to work, so you can either make it a ScriptableObject, or you can use SerializeReference
that said you might just find the simplest solution is to put all the possible fields in a single type and conditionally hide them in your custom inspector depending on a type dropdown or something like that
unfortunately that isn't an option, because I need the ability for users to create their own classes derived from ShaderPreset
I tried your idea for using SerializeReference, but the only thing displayed in the inspector is a label
for the following:
public class PresetTest : MonoBehaviour {
[SerializeReference] public AbstractPreset preset;
void OnEnable() { preset = new Preset(); }
}
[Serializable]
public abstract class AbstractPreset {
public void DoSomething() => Debug.Log("test preset");
}
[Serializable]
public class Preset : AbstractPreset {
public ShaderInclude[] additionalIncludes;
public string[] additionalDefines;
}
SerializeReference means you need to provide your own property drawer yeah, it doesn't have one by default
hmm, could I provide a generic one for the AbstractPreset that automatically generates all necessary fields?
if you have a way of determining those fields sure, once you go down this route it's all up to you to decide what you show
Ypu should just look on Github. There is many implementation.
I found this unity blog and it looks like for them it works out of the box, the only difference is they use interface:
https://blog.unity.com/engine-platform/serializereference-improvements-in-unity-2021-lts
It works only if you already have created your object.
If it is null, you have nothing showing.
yeah, you need to provide some way for the user to create an instance of something
here I'm assigning preset in the OnEnable
OnEnable is not called ?
ok, yeah, it started working after enabling the game object (facepalm) and adding [ExecuteAlways]
thank you very much
anything I should be aware of when using SerializeReference?
gotchas etc
renaming reference tends to break serialization
similarly for renaming classes/interfaces
I think people said you can do formally serialized as attribute but I dont think that has worked for me.
You can use Moved attribute
oh, good to know
how much cpu does an empty component consume