#archived-code-advanced
1 messages · Page 86 of 1
that was one of several possibilities I mentioned
ChessBoard.Instance is static
clearly
and probably DDOL
SO like I said - a DDOL object
so what you say is, if i get an instance of a class it will make it DDOL ??
No?
If you do DontDestroyOnLoad it will make it DDOL
You are likely doing so in ChessBoard
This is honestly #💻┃code-beginner stuff, just saying
i don't actually use don't destroy on load on chessboard
How do I write a string variable to a FastBufferWriter? And how do I read it from the FastBufferReader?
maybe if you showed the code we could have a reasonable conversation about it
Netcode's serialization system natively supports Unity's Fixed String types (FixedString32, FixedString64, FixedString128, FixedString512, and FixedString4096). The serialization system intelligently understands these fixed string types and ensures that only the amount of the string in use is serialized, even for the larger types. This native su...
How do you do pathfinding in 3d space with moving objects?
Just a graph that will change in run time
Then find out the most suitable data structures for the graph, probably octree
Say in A* pathfinding asset. Because the free A* pathfinding don't have much documentation
Haven’t used that
(There should be some algorithm to generate “nav mesh” in 3d in form of 3d tetrahedron or AABB and reduce the number of Vertices significantly )
Built into unity?
There's no built-in solution for that. You'd need to find an asset or implement it yourself.
That being said, it's very rare for a game to use true 3d pathfinding. It's usually faked in some way.
Interesting, do some 3D a* solutions use tetrahedrons in place of triangles?
maybe grab all the AABBs of the mesh of obstacles first, then a graph of only AABBs can be obtained, second for AABB of the mesh, project the triangles into the face of AABB and forms some triangular boxes or tetrahedrons, it should be a slightly easier approach, idk the detailed algorithm of generation nav mesh.
the space partition have bugs or cant handle all the cases, just an approach
eg if two AABB of obstacles collide....
What could be causing the second Debug.Log here not to print anything to the console, when the first Debug.Log prints? This is inside a coroutine that's doing stuff to a text. Trying to isolate the behavior because the "end" variable seems not to be working correctly in the for loop after, although it's not erroring out, it's just not going to the correct place in the text.
is what i expect to see, but then at callCounter 2
it's just this
why hide all the relevant code? I'll take a swing and guess you maybe aren't incrementing start and have collapse messages on or something, but you'll need to provide more for any real help
It's messy enough not to bother you with it, just wondering if there's a general thing that I might be missing. I don't think it's the collapse stuff
then show the whole console windwo
or just merge them into a single call to debug...
Ok it was a simple collapse lol, should I delete that and pretend it never happened? 🙂
No, we need to keep track of people that make silly mistakes.
hello! does anyone here have experience on doing byte-range downloads with DownloadHandlerFile?
im trying to download a single asset bundle but i want to download it in chunks and then appending them when they're done. i have 4 instances of this coroutine running at the same time
private IEnumerator DownloadChunkAsync(string url, double startByte, double endByte, int id)
{
Debug.Log(id.ToString() + "_start byte: " + startByte + " / end byte: " + endByte);
UnityWebRequest request;
#if UNITY_IOS
request = UnityWebRequest.Get(iOSAddressables_Url);
#elif UNITY_ANDROID
request = UnityWebRequestAssetBundle.GetAssetBundle(url);
#endif
// dlHandlerFile = new DownloadHandlerFile(Application.persistentDataPath + "/testbundle.bundle", true);
request.downloadHandler = dlHandlerFile;
request.SetRequestHeader("Range", $"bytes={startByte}-{endByte}");
AsyncOperation webRequestOperation = request.SendWebRequest();
while(!webRequestOperation.isDone)
{
float progress = Mathf.Clamp01(request.downloadProgress / 0.9f);
switch(id)
{
case 0:
progress1.text = (progress * 100).ToString();
break;
case 1:
progress2.text = (progress * 100).ToString();
break;
case 2:
progress3.text = (progress * 100).ToString();
break;
case 3:
progress4.text = (progress * 100).ToString();
break;
}
yield return null;
}
if (request.error != null)
{
Debug.LogError(id.ToString() + "_" + request.error);
}
else
{
Debug.Log("RESPONSE: " + request.responseCode);
runningDownloadTasks--;
}
}
When applying state machine pattern to a game.
Assume I have these states:
Idle, Walking & Running
What if I want to do something like if my player hp is less than 50% then he's injured and his movement is slow
do I make a new
InjuredWalking state? or how do I go about applying this
or do I track players base stats like hp, stamina & isGrounded and handle those within the same state?
maybe, but if you modify the speed (or other stuffs) (it is transitions) you have created a new state implicitly
But which is the correct path?
Like don't I need to check for isGrounded in all my states?
If you have many stats that have to be modified or handle some specific logic then FSM may be better
anybody know how to make a script that prevents playfab account spamming?
I've never had a playfab project that had that issue
Order of initialisation has been the source of a lot of problems in project starting from middle of production. Tips, suggesions or advice to tackle this?
- Write code that doesn't depend on execution order
- Rule of thumb is self-init in Awake, init that depends on other objects in Start
- In cases where that's especially difficult, use https://docs.unity3d.com/Manual/class-MonoManager.html to enforce execution order
main thing is to try to avoid dependence on execution order
another is to bring things into existence as they are needed
I found that rule of thumb intuitively but since I am dealing with 2 other programmers I of course don't know if this rule is followed everywhere (since it is in the technical document of the project)
This is what code review processes are for
Indeed, but since this is a school project and they introduced code reviews quite late the damage was already done
You should modify script execution order, and only for a few super important classes that you know need to go first/last
Time to go back and refactor a bit then
and now not enough time is present to fix it fundamentally
Well look, you've been given the advice you asked for
Yeah seams like our best case but I feel like their are going to be codepency shenanigan problems 🙂
Yeah my bad, I appreciate it
fixing bad code is always harder than writing it correctly the first time
Thanks for that link btw
For systems / managers and hooking gameloop events how can you avoid the execution order ?
some scripts need to have defined execution order. Example: Custom physics solver needs to go last. Menu to control the whole game mode should probably go first
system/managers usually non-dependent which would usually be awake
WDYm by "hooking gameloop events"
In our case there are events of the game loop that are hooked to for example terrain generation and vice versa
but you may run into situations where you need a gamemanager (service locator for these major systems) to load first for these systems, so loup's suggestions for custom execution ordering
In general, the moment a script comes into existence, Awake() then OnEnable() get called
Start() waits a bit before going off
Can't think of a good example, I'll look at the code if I can spot something
Yeah I am aware of that but not sure if the others kept it in mind
then you are working with people who wrote bad code
i once inheritted a 1000-2000 line script with highly technical calculations for a very specific machine. No comments, and all variables were just named a/b/c/d/e/f/g…
My solution: Toss it out
all of it. garbage
not salvageable
would take more time to fix than to make from scratch
yeah, I am fairly certain one of my programmers wrote bad code
sucks. deal with it as a people issue. not a coding issue
let him know he fucked up
save the next person some grief
haha
Order of initialisation has been the source of a lot of problems... for systems / managers and hooking gameloop events how can you avoid the execution order ?
when execution order matters, you're seeing hard, irrefutable evidence that
- just because you can point to one piece of code and give it a name ("InputManager")
- and then point to another piece of code and give it a name ("PlayerAnimationController")
- doesn't mean that the two pieces of code are actually decoupled
does that make sense?
for example, you CAN name this group of code playeranimationcontroller, and you CAN name this piece of code inputmanager, and then you CAN have them reference each other, and you CAN make a bunch of flags so that you mute certain inputs while certain animations are playing, and you CAN pipe a bunch of input state to the animation controller to show stuff at the right time
and you CAN make a dependency injection framework that somehow resolves this.
BUT that doesn't mean they're decoupled. they're strongly coupled. you just pretend that they aren't
Yea 100%
so it's really hard to communicate this to your teammates
i haven't really succeeded. it's better to come in with a very strong opinion with a name for your tightly coupled thing
sometimes people aren't ready yet for the Morpheus-esque rabbit hole of strongly coupling stuff and being happy about it
it's easier than it looks. you can literally copy and paste the the code from one class into the other, and delete the old class
it's not as buggy as it seems, or take as long as it seems, and it also fixes a ton of bugs on the journey. you have to do that anyway. you have the bugs
anyway i am validating your strongly held beliefs
Will read later
basically there's an expanding brain meme
0. i have a Player class, everything lives inside of it, like the player's health, their input and animations
- brackey said
InputManagerandPlayerAnimationController - i'm going to use dependency injection (or similar) to share controllers with each other
- i'm going to move everything to one class again, but only the things that really need to share state with each other, called
FirstPersonPlayerController. it will be separate from aHealthAndEffectsController. - all tightly coupled stuff will be in the same classes.
the big picture is that you can have multiple state machines, and have a "one way" representation that interprets those states and tells you "slowed down" or "not slowed down". it's tedious but it's bug free
I am having a hard time locating the old thread that has discussed the state of Unity and large files greater than 4gb. Since I cannot use the XML gcAllowVeryLargeObjects, what is the latest?
In short there was talk about updating Unity to the newer .net version and allowing it
I agree with you, I do my best to reduce coupling through events in the sense but I am fully aware that it is not actually decoupled
How can I set a constant Buffer in a shader?
I have a struct containing diferent variables that will be constant, and I would like to set them in one go to the shader
I created the buffer like this
if(SettingsBuffer != null)
{
SettingsBuffer.Release();
SettingsBuffer = null;
}
float[] setts = new float[] {
vegetationSettings.ClumpingSize,
vegetationSettings.SizeVariance,
vegetationSettings.ColorVariance,
vegetationSettings.VerticalSize.x,
vegetationSettings.VerticalSize.y,
vegetationSettings.MaximumDensity,
vegetationSettings.Slope.x,
vegetationSettings.Slope.y,
vegetationSettings.SlopeBlendFactor,
vegetationSettings.MinHeight,
vegetationSettings.MaxHeight,
vegetationSettings.HeightBlendFactor,
};
SettingsBuffer = new ComputeBuffer(setts.Length, setts.Length*sizeof(float), ComputeBufferType.Constant);
SettingsBuffer.SetData(setts);
And then set like this
IndexDistributor.SetConstantBuffer(VegetationSet.vegetationSettingsID, VegetationSet.SettingsBuffer, 0, VegetationSet.VegetationSettings.Size);
And defined like this in the shader
cbuffer vegetationSettings{
float ClumpingSize;
float SizeVariance;
float ColorVariance;
float2 VerticalSize;
float MaximumDensity;
float2 Slope;
float SlopeBlendFactor;
float MinHeight;
float MaxHeight;
float HeightBlendFactor;
}
I'm using UnityGB to emulate a Game Boy game I'm making and I want to send a variable from my Game Boy game to my Unity game. Anyone have any clue if this is possible?
you can Save then read the saved memory
Is there a way to decode that byte array into something that I can understand? lol
Do you mean you're running a GB game you made yourself through the emulator?
Yep
With GBStudio
well...
i don't know what you expect
you can certainly blub your way into it. save the game, make the action in the game that changes memory, save the game, diff it
am i going to question the wisdom of deeply chasing a trend where there's one viral mcdonalds branded experience and one more retro gb studio experience? no.
Does the save function in UnityGB save the state of the game in the emulator? Because if that's what it does it's basically impossible for me to decode those changes right?
If the player is one pixel off from where i want them to be it'll be screwed up right?
i think maybe your best bet is asking the gb studio people
Well I guess if it's like an unchangeable screen maybe that'd have the same save state every time?
you would modify the memory state directly. the saving is to give you an opportunity to analyze it
you wouldn't replace the whole memory, just modify a tiny part of it
i'm sure there's a way you can access the emulator memory directly
the gb studio people will know best
it's a fookin gameboy, it's going to just be addresses in memory
it's not like there's "reflection for ancient dead retro stuff"
The Emulator class in UnityGB does not expose the virtual memory, but you would just need to make its x80 field public, and then you can access methods like ReadByte to read directly from some memory address. I don't know if GB Studio allows you to write directly to memory at specific addresses.
I think it might be able to do that with a plugin or some advanced stuff
That's a really good place to start, I'll check with the GBStudio Discord, thanks guys
Hello guys how to make source Engine Movement 🧒
@round ledge Maybe you can do code that?
do anyone know how we can get the audio which is playing on the desktop like spotify or youtube in unity editor or applications
Most likely a windows API if it is about a windows function.
Do you mean the name of the song or the actual audio?
just need the audio
I'm not really understanding how to get world position of mesh vertices. I have a custom water wave function that uses a mesh of tris. I want the water to follow the player around but have waves work from world space instead of local space so that the ocean appears to be larger than it is. I have tried to use matrix 4x4 and Transform.TransformPoint but neither seems to be working (I'm probably not using them correctly) so any help would be appreciated.
Here's the full script without TransformPoint or Matrix attempts.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Waves : MonoBehaviour
{
public float linearWaveSpeed;
public float linearWaveHeight;
public float linearWaveLength;
public float rippleWaveSpeed;
public float rippleWaveHeight;
public float rippleWaveLength;
public Transform waveOrigin;
Mesh mesh;
MeshCollider physicsMesh;
Vector3[] newVertices;
void Start()
{
mesh = GetComponent<MeshFilter>().mesh;
physicsMesh = GetComponent<MeshCollider>();
newVertices = mesh.vertices;
}
void Update()
{
if (linearWaveLength < 0.01f) linearWaveLength = 0.01f;
if (rippleWaveLength < 0.01f) rippleWaveLength = 0.01f;
for (int i=0; i<newVertices.Length; i++)
{
Vector3 vert = newVertices[i];
float dist = (vert-waveOrigin.position).magnitude;
newVertices[i] = new Vector3(vert.x, (Mathf.Sin(Time.time*linearWaveSpeed+vert.x/linearWaveLength)*linearWaveHeight) + (Mathf.Sin(Time.time*rippleWaveSpeed+dist/rippleWaveLength) * rippleWaveHeight), vert.z);
}
mesh.SetVertices(newVertices);
mesh.RecalculateBounds();
physicsMesh.sharedMesh = mesh;
}
}```
You need to transform the position of the player in local space of the mesh.
i haven't set the object to follow the player yet
i can make the water object follow the player but because the waves are using local coordinates, the ocean seems like a static object that follows the player. The idea is to "scroll" the area of the ocean that is "loaded in"
perhaps I'm still not understanding.
The water is following the player ?
remember that vertex data does not have a transform. it is a vector3
Why would you use the vertex data ? You want the position of the player in the local space of the water dont you ?
What are you doing ? Because it does not seem like we understand each other correctly.
When moving the ocean, the waves "move with it"
the waves should be entirely based on world coordinates regardless of the position of the ocean object
Because you are working in local space and not in world space.
mesh vertices don't have a transform
ok so I would take the "vert" vector3 and run this function there?
tranformPoint seems to want a position rather than a vector3. Would it work if I make new transform data using vert?
No idea what you mean, but you want to use world coordinate then convert it to local space. So,
For each Vertex:
- Simulate the ocean in a world space coordinate
- Transform the vertex in local space with Transform.InverseTransformPoint
A position is a Vector3 ... ?
ok so here's my loop, if I'm following this correctly.
{
Vector3 vert = newVertices[i];
Vector3 worldPos;
worldPos = vert.TransformPoint();
float dist = (vert-waveOrigin.position).magnitude;
newVertices[i] = new Vector3(vert.x, (Mathf.Sin(Time.time*linearWaveSpeed+vert.x/linearWaveLength)*linearWaveHeight) + (Mathf.Sin(Time.time*rippleWaveSpeed+dist/rippleWaveLength) * rippleWaveHeight), vert.z);
}```
Vector3 does not contain a definition for TransformPoint.
using vert.Transform.TransformPoint(), vert doesn't contain a Transform.
I don't want to be mean, but you should start by learning how to code before trying to deals with subject like that.
am I using the function incorrectly?
Use Assets from the asset store or try to use built-in function.
assets don't have working buoyancy based on mesh collision.
i am $40,000 in debt for learning to code lol. Doesn't mean I'm good at it.
You clearly do not understand the basics and I have a really hard time communicating with you because of that.
There is multiple that does actually.
I'm not really understanding how to get world position of mesh vertices. I have a custom water wave function that uses a mesh of tris. I want the water to follow the player around but have waves work from world space instead of local space so that the ocean appears to be larger than it is. I have tried to use matrix 4x4 and Transform.TransformPoint but neither seems to be working (I'm probably not using them correctly) so any help would be appreciated.
Here's the full script before TransformPoint or Matrix attempts.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Waves : MonoBehaviour
{
public float linearWaveSpeed;
public float linearWaveHeight;
public float linearWaveLength;
public float rippleWaveSpeed;
public float rippleWaveHeight;
public float rippleWaveLength;
public Transform waveOrigin;
Mesh mesh;
MeshCollider physicsMesh;
Vector3[] newVertices;
void Start()
{
mesh = GetComponent<MeshFilter>().mesh;
physicsMesh = GetComponent<MeshCollider>();
newVertices = mesh.vertices;
}
void Update()
{
if (linearWaveLength < 0.01f) linearWaveLength = 0.01f;
if (rippleWaveLength < 0.01f) rippleWaveLength = 0.01f;
for (int i=0; i<newVertices.Length; i++)
{
Vector3 vert = newVertices[i];
float dist = (vert-waveOrigin.position).magnitude;
newVertices[i] = new Vector3(vert.x, (Mathf.Sin(Time.time*linearWaveSpeed+vert.x/linearWaveLength)*linearWaveHeight) + (Mathf.Sin(Time.time*rippleWaveSpeed+dist/rippleWaveLength) * rippleWaveHeight), vert.z);
}
mesh.SetVertices(newVertices);
mesh.RecalculateBounds();
physicsMesh.sharedMesh = mesh;
}
}```
Here is the built-in solution: https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@14.0/manual/WaterSystem-scripting.html
Here is an other solution I used in the past that support buoyancy out of the box: https://assetstore.unity.com/packages/tools/particles-effects/kws-water-system-standard-rendering-191771
I got it going so thanks
Anyone happen to know which dll of unity's contains UnityEngine.UI.Button? I'm referencing the UnityEngine.CoreModule.dll and other assemblies, but my class library can't find the UnityEngine.UI namespace or assemblies. Other UnityEngine namespaces appear to be functioning as expected.
After building the unity app and pulling the unityengine.UI.dll managed folder; that ones seems to actuall work and resolved my issue.
Is there a way to get something like Try Server (Method with only NetworkSerializable Params), which will simply execute the function when offline but can do a specified behavior if we are online, like simply calling the method on Server Rpc. I use this line of reasoning for my code all the time using ServerRpc so this in simpler terms would be very useful.
- isServer - true if the GameObject is on a server (or host) and has been spawned.
- isClient - true if the GameObject is on a client, and was created by the server.
- isLocalPlayer - true if the GameObject is a player GameObject for this client.
- hasAuthority - true if the GameObject is owned by the local process
https://docs.unity3d.com/2019.4/Documentation/Manual/UNetAuthority.html
I know thats possible but I want to be able to TryServer without multiple functions and many lines of code. How would I even start coding osmehitng like this?
It is one line of code ?
Also, a ServerRPC works in an offline call ?
it does?
Like, you do not even have to check if it is online or not.
doesnt seem to execute when I try it
You pretty much just need to spin the server and not expose it.
A.K.A the library. (The client is the server)
hmm... how would I do this exactly? and how would I, when I need to actually connect online, seamlessly turn off this?
would it be something like this?
Relay.Instance.CreateAllocationAsync(1);
You wouldnt want a Relay though.
A relay is external server which client communicate through to facilitate connection.
NetworkManager.Singleton.StartHost();? how would I relably shut it down beofer game start
Do not know what to say. You just follow a tutorial on how to setup netcode for GameObject.
You do not want to shut it down.
You need the host active
what about when you want to connect to another player's relay?
Then you switch ... ?
I do not know, it seem to me like you are asking the specific which you wont get there.
I can guide you with the general idea, but that is pretty much it.
NetworkManager.Singleton.StartServer(); // Starts the NetworkManager as just a server (that is, no local client).
NetworkManager.Singleton.StartHost(); // Starts the NetworkManager as both a server and a client (that is, has local client)
NetworkManager.Singleton.StartClient(); // Starts the NetworkManager as just a client.
SceneManager.LoadScene(joinedLobby.Data["KEY_GAME_MAP"].Value);
joinedLobby = null;
JoinAllocation joinAlloc = await RelayService.Instance.JoinAllocationAsync(joinCode);
RelayServerData relayData = new(joinAlloc, "dtls");
NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(relayData);
//MonoPlayer.monoPlayer.SetActive(false);
NetworkManager.Singleton.StartClient();
NetworkManagerUI.s.Destroy();
so running this code while a host is running would work correctly?
Using an IP address of 0.0.0.0 for the server listen address will make a server or host listen on all IP addresses assigned to the local system. This can be particularly helpful if you are testing a client instance on the same system as well as one or more client instances connecting from other systems on your local area network. Another scenario is while developing and debugging you might sometimes test local client instances on the same system and sometimes test client instances running on external systems.
No, you are still using a Relay...
nvm
how do I start a host when my project is connected to relay when I dont want it to connect to relay for that startup?
Any ML Agents expert? I need some help.
Do not connect it to relay. There is nothing else you have to do. Don't do what you do not want to do. A relay is optional, not necessary.
returns error: you must call setrelayserverdata() at least once before calling startserver.
I'm working on a game and i'm using a scriptable object to hold certain values, but these scriptable objects are on various scripts so i manually have to type in getcomponent for each script. Is there a way to directly get the scriptable objects values
like, and this is pseudo code, object.getcomponent-scriptable object
Well, no. Provide more context on what you are trying to do
Okay
So I am creating a spell system for my game and the scriptable object holds variables that are common to every spell
But because there are complex spells, they each need their individual script with different names
so i cant get this information through script
if (Input.GetKeyDown((x+1).ToString()))
{
Spells _spells = spellGameObject[x].GetComponent<SpellScript>().spells;
if (player.GetMana >= _spells.mana)
{
GameObject spell = Instantiate(spells[x].spell, spellPoint.position, Camera.main.transform.rotation);
int mana = player.GetMana - _spells.mana;
player.SetMana(mana);
}
} ```
spellGameObjects is a list holding the spells in player inventory
and SpellScript would be the spells script
this bit is pseudocode to show what i am doing right now
but its obviously inneficient and searching in unity documentation and forums helped me little
Well if the type of so in each spell is the same, why not have a base SpellClass that holds the So snd other common spell data/functionality and have all your spells inherit from that
That way you can GetComponent on the base type and access the data regardless of the concrete implementation
But then again I dont get why your spells are monobehaviours in the first place
Wdym?
should they not be monobehaviours?
Depends. Why are they monobehaviours now?
Their movement
that is the forward force
and i have this shotgun type spell, where 5 mini-fireballs shoot consecutively
this and for damaging player/enemy
You shouldn't be needing to use getcomponent more than once if this reference doesn't change. Grab it then bind it locally to access in Start(). Other methods is to bind SO reference to a Singleton so you can access it directly through that instance.
This is not an ideal architecture. You can read on Tell Don't Ask: https://martinfowler.com/bliki/TellDontAsk.html. In other words, you should call the function "Execute" on the spell and everything should be done inside this function. (You tell the ability to be executed, you do not execute the ability manually)
Also, as other suggested, you should use polymorphism/interface.
How can I get the max Value out of a native array in unity JobsBurst?
Since everyone is writing it and reading at the same time it would fail
in hlsl I can use InterlockedMax and it works, is there any variant to use in unity jobs?
Burst supports System.Threading.Interlocked, which is similar to HLSL's Interlocked functions. However, it doesn't have a Max function. According to this, it can be worked around with Interlocked.CompareExchange
Thanks!
Thank you very much
thank you
Hello, has anyone used before the factory pattern to provide "inflated types" to Monobehaviour types so that they actually can serialize them in the inspector?
Inflated types is the unity term for types that explicitly decide a type for their inherited generic types or interfaces
I'm trying to do all this because in unity you may either serialize a generic class with concrete type or a non-generic interface but not any mix of the two
So I thought I could add a factory somewhere that internally has inflated classes of the generic types I may ask for and returns these versions which are now serializable
But it seems like there is no escape to having to create a whole bunch of inflated types for every type parameter that may appear I my application and then doing the most awkward switch expression where I return a weird wrapper class that just is the same as the matched case but without the generic parameter
when you say serialize, do you mean, editor serialization, json serialization...?
you say serialize in the inspector
do you mean making a type appear when it is set on a field in the default editor inspector? i think you should just use a custom property drawer
it's simpler
Yes, all this is to provide nice editor inspector serialization
can you show me an example of a type?
Why would I get faster rendering time with multiple draw calls rather than a big draw call?
You'd find a balance through testing
So is it possible? I thought that less draw calls > more performance
Because I'm currently finding that and it seems that for some reason, many draw calls is faster than one singular big draw call
And i don't understand why
One example would be if you have a million objects in the scene, frustum culling and occlusion culling could reduce that to a very small number of objects, each with its own draw call.
Compare that to a single huge combined mesh which would be one huge draw call that could be extremely slow
No but im already doing that on both cases. So i literally have one huge draw call doing the same rendering amount as many smaller ones
But the smaller ones are faster than a single
I've been doing some mesh chunking, and for the most part I do try to eliminate as many draws as possible by combining meshes. But, eventually it does become a problem when they are too large, as editing them has an increasing overhead for mesh manipulation.
mmm, in my case im just rendering grass. So i have two options:
- A: Smaller buffer, calculate one chunk, save index, draw and repeat per chunk
- B: Big buffer, calculate all chunks, save all indexes, draw only once
For some reason, case A is faster
UI has a similar problem were you can pretty much have a single large UI, but if you were to move an element it would dirty the whole canvas.
it's funny because resources point to trying to limit draws to about 50 or 60 on mobile, but usually you do want to cut up the canvas a bit more if you do have a large UI based game.
Can I get all methods with a custom attribute from all of the scripts used in a scene?
I know I could iterate over every object active on awake but is there a right way to do it?
You'd have to iterate over everything
What's the use case?
I’m writing a custom in-game debug console and commands are added for it by an attribute
So you're trying to intercept any method call with the attribute and emit a log when it's called?
Sounds like you want aspect-oriented programming
Well, not like this. I’m getting all methods (as MethodInfo), storing them, and invoking them using reflection when it’s needed
Not sure that would even be sufficient. What stops someone from instantiating a prefab which now has new scripts on it that weren't in the scene before?
when is it needed?
When the user inputs the command into the console
Oh I see
you want to invoke a command
Shouldn't these be static methods then anyway?
Rather than related to objects in the scene?
Some, sure
If they're not static how do you know on which object to invoke them?
But the user might want to put it on the monobehavior
I have a class “ConsoleCommand” that stores the MethodInfo and the invoking object
So it knows what class contains this method
but if I write shoot in the console how do I know which character will shoot for example? All of them? Or do I need to say character --withName "Gary" shoot or something
Limiting to static functions seems like a good starting point
in that case you can basically just do SomeClassInMyGame.GetType().Assembly then search all classes in the assembly and find all static functions from there with the attribute.
I could specify how the method on monobehavior works. Like should it run for first found instance of the GO or all of them
sure
in either case I would use the assembly as the starting point for your reflection search
rather than enumerating objects in a scene or any other Unity concept
Alright
Enumerate all the types in it with: https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.gettypes?view=net-7.0 And go from there
Do you know how the default Unity user assembly is called?
It's Assembly-Csharp but I would just grab it from one of your classes like this
or rather typeof(SomeClassInMyGame).Assembly
It would be a good solution, but I have a separate assembly for my console because it’s in a Unity package
In that case I would probably do something like:
public void InitWithAssembly(Assembly a) {
// do all your reflection here
}```
and call that from your main game code
Alright, thanks for advice
Generally speaking, less draw calls is better. However, it is not always the case as you have seen. An example would be that if you make to big batches, you cannot efficiently cull the batches making it draw more than what it needs to.
any idea what could cause this? it thinks itself is null...
the component is destroyed. this is an unfortunate side effect of the unity API
how so?
that field is showing you the ToString on the object, but not..
ok.... but it clearly isnt destroyed if the code is being executed on it??
The C++ representation of the component has been destroyed.
that is what's happening
the code is being executed
the object is Destroyed according to unity's representation of the scene
its ToString is showing "null" for idiosyncratic reasons related to how Unity overrides ToString and equality comparisons with null
ok
the situation where this is really null can happen, which ahs nothing to do with unity, but you haven't shared any code
so i can't rule that out
it's very very hard to get into such a situation
so it's extremely unlikely that some layperson on the internet using unity got there
you are almost certainly stepping through a coroutine, and you almost certainly have code which calls Destroy on the game object
at some point
i cant share the code is there a thread or something wehre i can dump a lot of text?
i think the answer is already resolved so i wouldnt' worry about it too much
are you stepping through a coroutine?
okay
private void Preround()
{
readyButton.interactable = true;
readyButtonText.text = "Ready"; readyButtonText.color = Color.cyan;
tr.ReadyText.text = "0 / " + playerObjs.Count;
//Even if i try and set Rig right now, it says that GunPlayer doesnt exist... WHY???
Rig.velocity = Vector3.zero; Rig.rotation = Quaternion.identity;
ShopSlot.Movable = true;
StartEndDepend(true);
if (!inititalPreround)
SetScoreServerRpc();
}
okay, that is sufficient
the object is destroyed
destorying an object does not unsubscribe it from C# events
that's the whole story
does that make sense?
ok makes sense
How do you sort them? The order in which things get drawn affects how much work the GPU does, because of overdraw. When drawing opaque objects, you want to try to draw them front-to-back, so the GPU doesn't waste time shading pixels that will later be obscured by another object.
usually people do void OnDestroy() { ... GameStateMachine.OnPreround -= Preround; } but honestly just don't use C# events, call the thing directly.
exactly for this reason
Draw call batching is a balancing act between optimizing to minimize state changes / SetPass calls / draw calls, and drawing with ideal front-to-back sorting to minimize overdraw.
OHGHHH I GOT IT! tysm
yeah
just think very deeply about "destorying an object does not unsubscribe it from C# events"
it was just cause I "refreshed" objects by reinstantiating them which made it look like the refreashed object, not destroyed, was calling that but instead it was the object pre-refresh.
Indeed, in my case I'm pre culling it already on both cases, so it wouldn't be affected by that
In my comparison it doesn't matter because in both cases they are all drawn (with draw mesh instanced indirect)
But in my case the set passs calls and draw calls are reduced and there's no performance increase
It does matter. Instanced draws still have an order and are affected by overdraw.
But if in both cases they are all drawn the order doesn't matter (because it affects the both comparisons equally)
In any case, the case where I was doing the check there was no overdraw possible (since none where occluded by anything else or themselves)
The Set Pass call is the expensive bit, not the draw call. If you are drawing each batch with the same material, then Unity doesn't need to change the material between them.
If the grass is not writing to depth, then you would have to ensure correct sorting, or the grass would render on top of grass behind it, if drawn in the wrong order.
I'm actually , when doing all the calls, doing draw call of material X, draw call of material Y, draw call of material X, draw call of material Y,... because of LOD's, so set pass is bigger, and performance doesn't change (it stays stil slightly faster)
it is writing to depth, (deleted the old message) but i was looking from top where none of the blades are on top of any other blade
I'm just gonna stay on the multiple draw calls, for some reason it stays slightly faster and memory consumption is extremely different (I can do the multiple draw calls in just 20Mb, while the single draw call requires minimum around 800-900Mb or more even, for a 1 frame difference at best)
But it's weird, will look further into it on the future
Anyone have any ideas why I can build locally but when I try to build using unity automation cloud build im getting a gradle error.
ERROR: Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details
copy
you can ignore that error, it is a red herring
these things depend on so many factors so benching is the right approach. for example shared memory gpu like phone or the switch can do rings of back and forth with the cpu, 2060 on windows prefer big chunk - what GPU?
Why does this fail when I build?
[System.Diagnostics.Conditional("UNITY_EDITOR")]
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
public abstract class VfxAttribute : Attribute {
public string Name;
protected VfxAttribute(string name) {
Name = name;
}
public abstract void Append(VisualEffectSummary summary);
}
Assets\_Game\Scripts\EditorRuntime\VfxAttributeProcessor.cs(24,33): error CS0246: The type or namespace name 'VisualEffectSummary' could not be found (are you missing a using directive or an assembly reference?)
Elsewhere:
#if UNITY_EDITOR
using System.Text;
using UnityEngine.VFX;
namespace EffortStar.Editor {
public readonly struct VisualEffectSummary {
Does ConditionalAttribute not work?
I don't think it works the way you think it works when applied to an attribute like that
So I want to set the velocity in accordance with the players rotation so if he was going up a wall the vector would be (0,5)
with some help from chat gpt I came up with this, this does work however because I am hard setting the Y value gravity is getting cut off when there is horizontal movement. I just don't how to factor gravity back into the formula.
void Move(float horizontalInput)
{
if (horizontalInput != 0)
{
// Get the player's rotation in radians
float playerRotationRadians = Mathf.Deg2Rad * transform.eulerAngles.z;
// Calculate the movement vector based on player's rotation
Vector2 movement = new Vector2(Mathf.Cos(playerRotationRadians) * horizontalInput * moveSpeed,
Mathf.Sin(playerRotationRadians) * horizontalInput * moveSpeed);
// Apply the movement vector to the rigidbody velocity
rb.velocity = movement;
Direction = (int)Mathf.Sign(horizontalInput);
// Flip the sprite based on the direction
spriteRenderer.flipX = Direction == -1;
}
}
Any tips on how to approach the third step on this? It's suprisingly difficult for me, as doing pure distance checks either are extremely nested, or fail because of members of the squad moving away together, therefor always having someone close enough to not be considered outside of bounds.
so when they merge do they just become 4 of those? and then they can just randomly separate or?
Yes, when they move together they check if they are in opposing squads, and merge into one.
Distance
well if the issue is that they never get outside of the boundary to be out of bounds, just sounds like the second squad pair just moves too fast and keeps up with the first squad pair
so you'd probably want to slow down all secondary squads
or speed up the main squad as it collects squads
No, not the issue of speed. Its finding a way to detect if your outside the group or not, if someone is near you, but he also is to far away from the next member etc etc. its a very nested thing, with each iteration requiring checks to every other squad member making it more expensive. I was wondering if there is any tricks I have missed. Maybe some kind of pathfinding between units to see if there is a valid connection is the soloution, I havent tried that appoach yet.
if you're just checking when it's too far away could you just use a collision trigger around the main squad and whenever something exits that trigger aka goes outside the boundary you can disconnect that squad
probably just a sphere collider
There is no main squad, they are all the same, and split into two
Yeah I think I don't quite know enough about your games mechanics to give you a solid solution
Do you have any video gameplay of what it currently does?
I'm going to head to bed but I'll check out any other resources you post tomorrow
I'm in Arkansas digging for diamonds as a vacation but I'll be on later at night
Yeah no problem, thanks for trying. I'm looking into clustering algorithms today we'll see if that helps. sleep well :)
I'm in gtx1060
Is there a callback for when the Scene window is interacted with?
how do you fix vr Controllers when they have trails
#🥽┃virtual-reality i guess.
But provide way more info
I have a parent enemy class, and many different scripts for each enemy (inheriting from parent enemy class). How do i call the damage function in parent enemy class?
Assume the player hit the enemy using a raycast and has all that information from the raycast
i do not want to call the base implementation
the problem i am having is
i have scripts called goblinAI, slimeAI, spiderAI
and i want one line to call the damage method for whatever the enemy is
instead of checking if its a goblin, slime, or spider, then getting that script
but you are asking "How do i call the damage function in parent enemy class?"
cant you call it as usual eg enemy.damage()? though the overrided version will be called through vmt
you know you hit an object- and you want to get the goblinAI, slimeAI, spiderAI component from it. Since these are all derived from EnemyAI (or whatever you call it), you can use EnemyAI enemy= hitObj.GetComponent<EnemyAI> on the object hit. and if you get one thats not null, simply call enemy.Damage()
@lapis summit
this is basic C# polymorphism 🤔
Look up virtual methods and how to override them
rather, that's assuming you've extra logic between enemies. Otherwise you can just reuse the class mostly
Such that you have a single Enemy class with different scriptable objects of enemy data that you can insert into it
Editor bug, can ignore
I think I found the cause , scripts can cause the error as well.
It's not popping up anymore and in a script I had
[serliazeField]
private TextMeshProUGUI varsiableName = null;
I removed the = null on global declaration
That shouldn't change anything, null is the default value anyways. I suppose that recompiling scripts just made the editor bug go away
your right it's still popping up
i tried this
and its not working
one sec
please show us
i'll tell you the exact error
Oop
Its working now.
I really appreciate all of your help, even when i was being so thick 🛐
Now i just have to learn State machines :)
I'm having a problem with an asmdef, I can't seem to add managed osx or linux dlls to it, just windows
If I manually add it to the asmdef file, it shows as none in the editor
Look up on Youtube Finite State Machines
precisely what i'm doing
sick
i mean i looked it up a month ago
but kept procrastinating
but what i want to do, is have a 'local' state machine
Oh dw same, theres little ab state machines online compared to other things unfortunately
Igu
I dont want to have to create new scripts for Attack, Run, Defend blah blah
i want it all to be in the same script
i did do a sort of state machine, without knowing what those were, with my attack function, so i could recreate that for my whole enemy
what game are you working on? if at all
I just want to complain for a moment that CustomYieldInstruction does not share a common type with YieldInstruction and AsyncOperation does not implement IAsyncOperation.
This makes abstracting unity's built-in api troublesome :/
Unity is lacking serious support when it comes to abstraction
Not sure what right channel for this question is, but we are changing scripting defines in a custom build script when running build from cli using PlayerSettings.SetScriptingDefineSymbols. The problem is that the changed script defines arent being reflected in the code during build, so its not properly refreshed. I tried all things like manually calling refresh on assets, or even trying to trigger a script compile. Only way I have gotten it to work is to do it in 2 seperate cli calls, where the first one only changes the script defines, and 2nd does the build. But its really not an optimal flow as it adds lots of overhead to build time. Anyone encounted something similar, and how did you solve it? Only other fix i can think of is making the script define changes directly to the ProjectSettings.asset from external code
how much overhead are we talking? I'm currently doing it in one pass like you want and was actually planning on switching to two passes instead because I think it'll be simpler and more reliable
but atm I'm just using a build method that:
- locks assemblies
- applies scripting defines
- saves session state so the build will resume after domain reload
- unlock assemblies
- force assembly reload
Then in a [DidReloadScripts]-decorated editor method, I check those SessionState values and resume the build, but now with the changed symbols
How do you do that third and fifth step?
I mean, its not a crazy overhead, 3-4 mins, but for us we want to have as fast build times as possible since its a key part of our CI/CD process, so I rather not do it like that. I now have a python script that changes the values directly on ProjectSettings.asset instead. Found a python module called unityparser that helps me make the changes "safely". Annoying that its not standard yml 🙂
https://docs.unity3d.com/ScriptReference/Compilation.CompilationPipeline.RequestScriptCompilation.html with the clean build cache option, and literally just https://docs.unity3d.com/ScriptReference/SessionState.html since obviously you can't hold anything in script memory
I like the python option though, that seems like a clean solution
I tried a bash script to edit ProjectSettings and it's definitely way too much hassle to bother with
If I'm creating, using and disposing a native array of temp job multiple times, would it be better to create it once as persistent and reuse it?
Yeah, it's a pretty low hanging fruit optimization, but probably only worth doing for hot paths.
Probably, but if the code to maintain that cached array is too complex, it might not be worth it.
Creating temp arrays instead of persistent arrays can reduce how much memory your game needs at the same time. For example, if you have five separate systems running sequentially, and each needs their own 200 MB array to do some work, they could save processing time by allocating their array once and reusing it. But then you have five 200 MB persistent arrays allocated at the same time, at a total of 1 GB. If they each used a temporary array, then you'd never go over 200 MB of allocated memory at the same time.
You can reduce allocation time by specifying uninitialized memory, which can make a difference when allocating a lot of bytes.
Is it possible to turn Domain reload on/off per assembly?
what is the purpose? are you using a build tool like bazel or gradle?
Does that apply with a temp array and a persistent, or also with a TempJob and Persistent? I thought TempJob was like persistent but with less life time (so it could go to 1GB)
It would be an arrat of arrays that would be select the available arrays before scheduling the job (typical object pooling)
(in this scenario, the arrays are always the same size and data type)
I’m trying to build a native plugin in c++ in vs. I’ve been following the wiki guide and d3d11 code sample from GitHub, but I can’t get the build to go because of a bunch of syntax errors in IUnityGraphicsD3D11.h. I could only find one question that is having the same issue as me, but it was never answered. Here is a link to the script and the build output.
A simple unsafe list of unsafe list (or native list/array) can do object (list) pooling
havent written native graphics library
btw i have took a look on the header IUnityXXX on my machine and found they dont include the d3d11.h
try to put the include of d3d11.h to the top of your code (ie first line) to see if it fix the error
Currently it's at the 5th line, does order matter?
try it first, i am not sure since "include" is just simple text replacement
Looks like it does matter, that made everything except the OnGraphicsDeviceEvent errors go away
yep , idk why they designed the header in this way (usually we will design .h can be randomly put on top)
Hooray for learning new programming languages. I fixed the OnGraphicsDeviceEvent error by reordering the file, but now I'm getting these two 1>MSVCRTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) 1>C:\Users\user\source\repos\Unity Graphics Plugin\x64\Debug\Unity Graphics Plugin.exe : fatal error LNK1120: 1 unresolved externals
I'm hoping the second one is just header ordering again, and with any luck that will also make the first one go away
Interesting, is it because my file doesn't have a main function?
Looks like it is, I'm assuming I just need to return 1 or 0 but I get error C4430: missing type specifier - int assumed. Note: C++ does not support default-int now
Figured it out, and it finally successfully compiled. Now to hope it actually works. Thanks for the help!
there can be no main in dll, though you have solved it
https://stackoverflow.com/questions/33400777/error-lnk2019-unresolved-external-symbol-main-referenced-in-function-int-cde
Turns out I had the wrong project type in vs, I was doing an app instead of a dll.
Does anybody happen to know analytics SDK/provider that doesnt collect anything by default and allows anynomous events? So not collecting OS info, not any user ids or personal information, purely gameplay data? I think at least Unity and Firebase collect always something even with all flags turned off
Hello
I'm currently using command buffers to calcualte, draw, then recalculate, then draw using the same buffers
I wanted to move to URP or SRP for extra built in features, can I still do that there in some way? (I know that there are no command buffers there)
you would use renderer features instead
How does it work? in comparison to a command buffer
it's more complicated than I can simply explain in discord
good place to start your research
Okay
Do you know if it follows a similar workflow to command buffers? I see that it's a scriptable object with some events and such
i've never used command buffers I only know they serve similar purposes
i was doing some mild research and seems that renderer features are way harder to work with than command buffers,
so myb one day
I have sent this script before, but I want to know if it is correctly structured now? Please tell me what is not right here and what I can improve from an architectural perspective.
https://gdl.space/duwadegote.cpp
Just to be sure it's clear, SRPs make extensive use of CommandBuffers. What isn't supported is adding CommandBuffers to Lights and Cameras as a means to hook into the rendering pipeline.
Renderer features are certainly more boilerplate, but otherwise not really difficult to use once you have the feature set up.
- Not a formattting/structure poblem your Dispose() is not correct and will not unsubscribe anything
- there's some weird spacing in your interface list
- otherwise seems fine-ish. Maybe some inconsistencies in where attributes live (same line vs next line)
is there a reason why that is not allowed?
It's my first time getting more serious about architecture, that's why I asked. If you have anything else to add - please do, I will appreciate any criticism, no matter how small!
Adding CommandBuffers to Lights and Cameras is a simple way to hook into an otherwise closed off pipeline like the built-in render pipeline. But it's also limited; you can't run any code during those events.
URP is an entirely separate render pipeline, so they didn't choose to remove support for CBs on lights and cameras; they chose to not reimplement it and instead created Renderer Features.
This is a common theme in Unity's development. Start with something simpler, run into limitations, reimplement it to be more flexible, optimized, but sometimes more complex or boilerplate-y. See GameObject/MonoBehaviour -> ECS
It's more work to get started, but allows for more control in the long run.
Hi all, I've got a best practices question.
I'm making a builder game prototype where you click an object to select it then drag it around the screen. Selection is done via a ray cast from the mouse through the camera. The ray returns the objects collider, then I transform the position of the object every Update.
My problem is the transform between the parent and the child objects getting out of sync. Ideally, I think I want the child transform to be static, and the parent to be used. However, I've got my rigidbody attached to my child, so the parent transform will always stay static, but the child transform changes over time as gravity is applied to it.
Below are 3 examples, I'm currently using A. Is there a 'best practice' way to organise my components?
this script it ok ? https://gdl.space/xuxevurino.cpp
what is your objective? what is an anonymous event? do you mean aggregate statistics only?
Event without user identification. So yeah basically aggregate data. It's requirement from publisher to not send any identifiers. But we can for example send some info about player state and gameplay related events
okay. if i understand correctly, you need something that emphasizes how privacy focused and anonymous it is right?
you can use plausible.io
you can post directly to the api with a UnityWebRequest
@drifting hawk does this help?
why is there a rigidbody?
while you're moving it, make it kinematic.
Thanks, we will check it out
When an object isn't selected it uses rigidbody physics, but when it is selected I make it kinematic as you suggested 🙂
In the end, I went with moving the rigidbody component (only) to the parent, as that's the only component that can move the object 👍
Thanks for the help!
I have been thinking about a way to implement a state pattern with togglable states. I'm making a third person where the player can loses or enables different states he can enter, with each sometimes changing just a bit
Question about property blocks
I have a material and I set some variables everyframe to it
that material I make a copy of it once so set some buffers that will be always used and then I use a property block to set specific (because the material might also be used by other parts)
I want to make changes on the material and see them without having to restart the scene to regenerate all the materials
Is setting buffers expensive? or could I do that at every frame (and avoid remaking the material)
Doing this evry frame
instanced.SetBuffer(VegetationSet.indicesID, LODIndices);
instanced.SetFloat(VegetationSet.displaceID, DisplacementTexture.Size);
instanced.SetFloat(VegetationSet.colorVarianceID, config.vegetationSettings.ColorVariance);
instanced.SetFloat(VegetationSet.maxViewDistanceID, config.ViewDistance);
instanced.SetFloat(VegetationSet.meshScaleID, config.meshSettings.MeshScale);
instanced.SetInt(VegetationSet.selectedLODID, lodLevel);
instanced.SetInt(VegetationSet.instancesID, config.BladesInChunk*config.BladesInChunk);
instanced.SetInt(VegetationSet.totalInstancesID, config.TotalInstances);
instanced.SetInt(VegetationSet.resolutionID, config.meshSettings.Resolution);
instanced.SetInt(VegetationSet.itemIndexID, config.ItemIndex);
Can someone help me set up Steam login? None of the code on the docs page is working for me. I don't know what to call or how to call it.
https://docs.unity.com/ugs/en-us/manual/authentication/manual/platform-signin-steam
At the end it just says:
"You can use a Steam session ticket to log in or link using a Steam account. Call the following API to sign-in the player: SignInWithSteamAsync(string ticket, string identity)."
But it doesn't explain what ticket is or where to get it nor does it explain what identity is or where to get it.
I've set up a button that calls SignInWithSteam(), which then gets a response in OnAuthCallBack with Steam login successful.
But after that I don't know what to do next?
I finally got it to work, no idea if I'm doing it right, but it logs me in and I can get my player id so I guess it works.
Still no clue what half the variables in the doc are for:
both m_AuthTicket and m_SessionTicket are never used as far as I can tell
And I really wonder what this is supposed to do, I assume it's a typo on the doc page, but no idea what it does or if I need it
m_AuthTicketResponseCallback = null;```
I changed it to m_AuthTicketForWebApiResponseCallback which is defined at the top and actually used, but dunno if it's intended like that
Feel free to PM me if you know more about Steam login and can help me set it up properly
Has anyone ever worked on a fighting game before? For hitboxes I'm currently using OnTriggerStay (which has consistent results), to activate my hitboxes I'm using a coroutine who's timer is synced to the regular timescale which leads to inconsistencies. The reason why I'm not using FixedUpdate or fixed deltatime is because I'd like to be able to slow the game down and the main timescale but keep the hitbox logic the same (currently not the case and with fixed update they'd lose sync).
If i'd like to achieve this would I be able to utilise a 3rd "Update" for hitboxes which is called inside Update() and only fires after its own time delta has passed? I already see holes with it so if anyone knows a way to implement an additional custom fixedupdate or has a better suggestion please lmk
I know limiting the frame rate is an option along with throwing out scaling deltatime too so if that's the most sensible option do lmk
Ohhhh, I'm a goober, fixed deltatime is scaled properly, should be able to solve it now
Hey guys, this is a bit of an SOS because I really don't know what to do here.
If I can't figure this out, I probably have to scrap the months of work I've put into this project, because it is integral to the end product.
Context
I'm using Unity and the Timeline in a project made exclusively for video. In this video, I have a virtual screen that needs to play back certain video clips while recording.
Thankfully, Unity has included custom Timeline sample scripts, some of which can sync a video component's playback to the timeline. Since I am recording the playback of the timeline, this is useful.
The Problem
It is barely functional, in that it can only work in extremely rare cases and in most cases it just straight up doesn't even try to play the clip. I believe it was designed for realtime playback in things like games, but since in my application I would prefer that the graphical fidelity is high and the timeline plays back slower than realtime (especially with the performance cost of the built-in recorder codec im using), it seems like the video player just cannot keep up.
It seems like the way the playback works in the timeline is that it just tries to make the video player go and attempts to sync the video playback position if it gets out of sync.
What I need
If anybody with the necessary experience might be able to help me alter the sample video playback script, or develop some alternative solution, so that I can guarantee that the frame doesn't finish rendering the frame until video playback has caught up and is on the correct frame, I would really really appreciate that. Any amount of guidance or assistance is appreciated because I am very stumped here.
Splitting each individual frame into images manually is also not a viable option here. I need the ability to just drag and drop videos into it and have them play. Worth noting that I haven't transcoded those video clips because Unity transcoding quality is dogshit even at the highest possible quality to the point where it is completely unusable. Every single one of these clips are 1080p60 NVENC H.264, encoded on the same hardware I'm trying to play it back on.
That being said, I do not need the audio from these clips I'm pretty sure, so while it might be a nice bonus it is not necessary.
What is attached
I've attached a little video of me demonstrating the problem, along with a zip of the scripts included in 1.7.5 Timeline customization samples. I'm fairly certain I haven't modified any of it.
Alternatively if anybody would know a way to ensure that each frame in the video will definitely appear properly with a normalized value between 0 and 1 indicating progress through the clip I think I would have code that can provide that value to a script, in case you have no timeline experience or something
tldr?
i mean its mostly said in the What I need bit
the video player isn't playing back properly with the unity timeline
and this is being used for rendering a video so i need a solution that will definitely work when the playback is not running at the frame rate that the timeline is set to
youd probably need the context of what i wrote in that message though just so you fully get whats going on and dont offer solutions that arent really for the problem
Have you looked at not using the video player and instead something like a Raw Image component that would display a render texture of the clip? Sorry I'm on my phone and so can't watch the video or really try to understand the problem, but that might be a possible avenue to look at a bit closer since I've also had issues with the video player. (though for a completely separate problem)
i mean thats a way of doing it, I do specifically need to use a material for a 3D model though
the main problem is writing the code that will take a video clip and display each frame properly in sync with the timeline
not the way it's being rendered
and as I said in my original post manually splitting each clip into frames is also not a viable solution here
so id need to do that individual frame reading at runtime
and it seems that the only way to get frames from a video clip at runtime is to use a component like the video player
oh i have an old project that had something similar to this lemme try dig that up and see if I used ffmpeg in a way that can be repurposed here
oh looks like i actually might be able to
idk where the ffmpeg package from the asset store went though
oh its deprecated
Your use case seem to not be suitable for what the Video Player/Timeline has been made for. As per your test, the Timeline and VideoPlayer might have some assumption that are not being respected in edit mode. That being said, you might be able to do something more hacky by using the VideoPlayer.StepForward or/and VideoPlayer.time and a custom playable implementation.
To diagnostic what is happening, you could always try to hook to some the event.
yeah i think in this case I'm going to try and adapt the video player timeline sample to utilise some code I wrote in a previous project that extracts each frame from a video at runtime and just do that instead
the main thing i still need to figure out is how to ensure that the timeline will freeze until the video's frame has been rendered but i think i can try figure that out
this might be what i need actually
Has anyone succesfully set up Steam login? The docs page is all over the place and I have some questions about it.
Can you interact with an external database from Unity Cloud Code Modules?
Anyone know how I can get the IP of my Cloud Code Module? So I can whitelist it in my database?
I got a weird bug I can't fix. No matter the version, no matter the project, even a fresh install and fresh project, my unity will add a package from my roommate's github that errors and doesn't load. I can't log in and removing the glitched package only fixes it until i reload the project. Then it just gets added back in. I don't even know why it's adding to my project or what it is. The package is called VisualstudioInpectorEditor
Go to Project Settings -> Package Manager and look if you have any scoped registries in there.
Package refs are kept in your Projects Folder -> manifest.json and packages-lock.json. Maybe try removing them from there and see if it fixes it.
what are these logs from?
there's no context here
why would the IP address range belong to unity? they probably host on AWS, which means it could be anyone
Every single one of these clips are 1080p60 NVENC H.264
are these clips intraframe only? otherwise, there is no chance they will decode in the manner you want. are you playing back on windows?
this is so busted, i believe your machine is misconfigured
have you tried building the player and running it on e.g. a macos device?
Every single one of these clips are 1080p60 NVENC H.264,
@dusky kettle can you try converting one of the files to intraframe only using
ffmpeg -i input.mp4 -c:v libx264 -x264-params keyint=0:min-keyint=0 -c:a copy output.mp4
although it would be best if you installed the h265 codecs from the microsoft store and encoded with h265 intraframe only:
ffmpeg -i input.mp4 -c:v libx265 -x265-params keyint=0:strict-cbr=1 -pix_fmt rgb444le -c:a copy output.mp4
your machine might not be fast enough for multiple h265 intraframe 444 streams
i have no idea if these exact ffmpeg invocations will work btw, but they should be close enough
Looking for advice... I'm using the workflow for buttons that does the good old .onClick.AddListener thingy... So for example there would be Button MyButton; and then void Start(){ MyButton.onClick.AddListener(OnMyButtonClicked);} and finally void OnMyButtonClicked(){ // do something } Or something like that, you get the idea. Now imagine that I have 20 buttons like that. Adding and removing them is suddenly not very nice, since you need then to add/remove those delegate shenanigans from Start/OnEnable/OnDisable. Any ideas to refactor this or change the approach to avoid the hassle ? I thought maybe just make an array of serializable class that has reference to buttons and to some Actions, but then I still need to add listeners manually each time... any ideas??
Are you sure you need to remove them? You only need to remove the listener if the button outlives the object that's listening to it
In my games the UI usually persists for the entire runtime of the program so there's no reason to deregister listeners
That said, I have had this problem before and it definitely sucks, there are things you can try to bulk unsubscribe, but it really depends on your architecture at to what is best. Best imo is to sidestep the problem as I describe above.
EDIT: IGNORE EVERYTHING I SAY AFTER THIS, I've managed to get my alternative solution working to a level that I am pretty happy with. It does mean I won't be able to load big videos without huge wait times, but I didn't really need to do that anyways. Thanks for the help though!
it won’t build, i’ve been importing assets that are really high quality and turning off all compression so I can get a good looking video
i can try this
i have made a lot of progress on my own system though
of just buffering every frame when the clip is in the timeline and displaying them one by one
Anyone know how to disable culling from Graphics.DrawMeshInstanced?
I know the doc say it shouldn't do that, but in my case it clearly does some unwanted culling, and looking at the net it's apparently been a thing since 2020 - so I guess it's not a bug.
Is there a way to disable it? I can "fix" the problem by editing the impacted meshes to have ridiculous bounding boxes, but that's impractical as hell long-term AND it mean a big bunch of uneccessary calculations are being made somewhere inside Graphics.DMI
Hi
It shouldn't be affected by frustum culling, since it is part of the camera workflow. Graphics.DrawMeshInstanced doesn't have access to any specific camera afaik, making it physically impossible to do frustum culling.
Actually scratch that. I'm not entirely sure it's correct anymore.
Texture2D created by code need to be Destroyed manually, does that also apply to Texture2DArray?
Texture2DArray inherits from Texture, so likely yes. Anything that inherits from UnityEngine.Object needs to be destroyed manually
okay thnaks
Not sure if it works the same, but at least for Graphics.DrawMesh frustum culling still applies and I had to mess with the bounds.
Although a very simple way to ensure a mesh won't get culled is to just center its bounds to a known visible point.
my machine is running a 3090 ti
if the video processing is cpu bound i think a 5950x should probably be okay???
cpu bound decoding is probably much more expensive
but cmon 1080p60
i have the h.265 codecs so ill run those ffmpeg commands
😬
ill double check that microsoft store reinstalled them when I reset my windows install
yeah
regardless i would thikn libx265 wouldnt require this anyways
🤔
yeah i have no idea
no scoped registries and i tried deleting the package refs and they also generate back with the errored package adding itself back in.
okay are you still interesting in encoding in 4444?
the options are -tag:v hvc1 -g 1 -profile:v main444-intra https://trac.ffmpeg.org/wiki/Encode/H.265#Losslessencoding https://x265.readthedocs.io/en/master/cli.html#profile-level-tier
do you have a gpt4 subscription? you should be using it to deal with issues like these
it's all so formulaic
https://github.com/NuiN99/Scriptable-Variables/tree/main/Scriptable Variables/Assets
Anyone know why I cant reference any scripts outside of the root folder in this project?
For example in the VariableSO class, I cant access the WriteSceneTextVariable from it unless I put it in the same folder. Its not the assembly definition, I tried deleting it and it still happened...
Scriptable Object Variable sytem for Unity to greatly reduce coupling - NuiN99/Scriptable-Variables
It also isnt related to namespaces, I tried removing every namespace, still an issue. Im lost man
It was the god damn plugins folder
Cant access stuff outside of it from inside of it
lame
[VR] Hey, I am using XR interaction toolkit and was wondering how I could make posible that whenever I pick up object that has some buttons (ex. calculator) I could use joystick to use these buttons, instead of moving/teleporting. Using new input system.
Yeah I am not sure that I need to, but still... "there are things you can try to bulk unsubscribe" - like what, for example?
Do you have an example of the code you're working with?
Speaking of bulk subscribing, I've been actually removing a bunch of events because they do actually create a lot of trash/garbage
had all my items subscribing and updating their modifiers like 50+ events each ;)
instead I just use callback manager which just iterates through everything
eh iirc 4444 is only if I really need almost perfect quality and that's not important here, the issue is that the video player on the timeline just straight up wasn't working, so I built a custom timeline thing that just buffers the frames and freezes playback until its done buffering everything so the timeline unity recorder integration can actually capture the video playing back through the 3d scene
its being played back on a virtual screen and those advertising billboards irl can have some pretty shotty compressed video played back through them so idk more immersive lmao
i made a little background task indicator for it and everything lmao
im glad the background task framework is really simple
I'm trying to achieve what's in the comment. States and StateFactory/Repository are not Monos and they do have some parameters both in common and not
For example. Jump has jump height and available jumps, but falling and and grounded do share stuff like gravity
I really need some help. We can move to a thread if you like it more
It does, and I can find this bug been mentioned on reddit 6 years ago, and on Unity's own forums 4 years ago.
So clearly they either don't care about fixing it or it's somehow intended behaviour despite the documentation saying otherwise.
Been asking a bit everywhere and apparently no one know how to actually fix that. Guess I will just have to use another API than Graphics.DMI, which is a bother.
I don't think it's a bug. It seems an intended behaviour according to the docs. You can even specify what cameras to render it with.
The only thing that this call saves you is creating objects with renderers.
It still result in objects spread across an entire football field being culled out when the camera is pointing right in the middle of them.
And having to check every mesh that will enter the system for correct bounding box is extremely annoying work-flow wise, especially since Mesh.RecalculateBounds doesn't actually calculate something valid and you have to manually decide the box's parameters.
Guess I will just follow Reddit's solution of blindly forcing huge box on everything, but that's such a dirty way to dodge the problem, for something that should just have a boolean Culling/NoCulling parameter somewhere.
Maybe Graphics.DrawMeshInstancedIndirect is an option for you, I know that Unity definitely does not cull that because I had to implement frustum culling myself
I haven't looked in the other variants much. I already do culling, which is why I'm annoyed Unity is redoing some wrong culling on top of it, so yeah maybe it's time I check the others. Thanks for the info.
The new Graphics.RenderMeshInstanced, which replaces Graphics.DrawMeshInstanced, has a worldBounds parameter which optionally overrides the bounds of all the instances. Unity will still perform the frustum check, but only against this one bounds, not per instance.
anyone?
Ooh, that would be nice. Will check that one too then. Thanks everyone.
@kindred tusk please don't judge
hold on
trying to paste the code
so I mean "please don't judge the code you are about to see" lol
Why can't you paste it?
New laptop, new keyboard sorry
Heheh
Can't find backtick key
Lol got a 60% or something
oh got it
public Button ButtonRegisterOpen ;
public Button ButtonLoginGuest ;
public Button ButtonRegister ;
public Button ButtonRecoverPassword ;
public Button ButtonLogin ;
public Button ButtonRecover ; ```
private void OnEnable ()
{
if(ButtonLoginOpen ) ButtonLoginOpen .onClick.AddListener( onClickLoginOpen );
if(ButtonRegisterOpen ) ButtonRegisterOpen .onClick.AddListener( onClickRegisterOpen );
if(ButtonLoginGuest ) ButtonLoginGuest .onClick.AddListener( onClickLoginGuest );
if(ButtonRegister ) ButtonRegister .onClick.AddListener( onClickRegister );
if(ButtonRecoverPassword ) ButtonRecoverPassword .onClick.AddListener( onClickRecoverPassword );
if(ButtonLogin ) ButtonLogin .onClick.AddListener( onClickLogin );
if(ButtonRecover ) ButtonRecover .onClick.AddListener( onClickRecover );
}
Yes I am all ears
List<(Button, Action)> _buttonHandlers;
void Awake() {
_buttonHandlers = new() {
(ButtonLoginOpen, onClickLoginOpen),
//...
}
}
void OnEnable() {
foreach (var (b, h) in _buttonHandlers) {
b.onClick.AddListener(h);
}
}
void OnDisable() {
foreach (var (b, h) in _buttonHandlers) {
b.onClick.RemoveListener(h);
}
}
@daring pelican
May I ask, where did you learn your coding style?
help again
there are languages that enforce that kind of style, but I haven't seen it in over 40 years
Use scriptable objects
Or serialized reference
let me look serialized reference
The thing about SOs is. Every time I enter a new state I need to check if fields are updated...
You shouldn't put any mutable state in the SO
Thank you! I was trying to achieve something like this, I think that you showed me the way, appreciate it a lot!!
It's not mutable at runtime. But let's say the GameDesigner wants to test jump speed or run speed at runtime.
Also having JumpState with JumpStateParameter SO and each state with the related SO sounds kinda janky
Just read it directly from the SO every frame?
Make the SO be a factory for the state
Give the state a reference to the SO for its configuration
The state it returns can have mutable state
And read the updated fields in the SO
that's just the coding style I kinda adopted over time, it just evolved by itself
i didn't know that they used to code like that
although i am aware that most people would probably gouge their eyes if they saw that code
Oh yes, it stems from the time when we had to program using punched cards, well before your time I guess
So like
class JumpStateConfig : StateConfig {
public float Height;
State GetState() {
return new JumpState(this);
}
}
class JumpState : IState {
float timeElapsed;
//...
}
I see so like this:
using UnityEngine;
public class HumanRunState : HumanBaseState
{
private RunSO runSO;
public HumanRunState(HumanStateMachine currentContext, HumanStateFactory playerStateFactory, BaseState state) : base(currentContext, playerStateFactory, state)
{
IsRootState = false;
runSo = state;
}
[...]
public override void UpdateState()
{
Ctx.AppliedMovementX = Ctx.CurrentMovementX * runSO.RunMultiplier;
Ctx.AppliedMovementZ = Ctx.CurrentMovementZ * runSO.RunMultiplier;
}
}
It's borderline unforgivable
I find it rather refreshing, you carry on doing what suits you
Yeah, you'll need to pass more stuff into in factory function
But same concept
But then they do not show on the Inspector unless i go directly to the inspector of that SO right? Could make a custom editor for showing SOs...
It's fine until you need to work with someone else
yes ty very much i got it as you said
oh nice, will do hehe
not if you all do it. Any convention is OK so long as everyone sticks to it
which IDE are you using?
just visual stuido community edition, nothing special
Agreed, it's just that you won't find another
Anyway, I'm not here to shit on whitespace
yeah I wanted to point that out
I used to do some unique stuff and I realized it doesn't matter what I think looks good, you just pick the standard and get used to it
you can clean it up with a shortcut @kindred tusk 🙂
Yeah that's what @raven orbit was saying
yep
@kindred tusk last thing. does this makes sense? Instead to have to lurk for the SO in the project. Visible and changable from inspector could be cool. (I'm trying to make this easy to understand and flexible FSM for people not used to unity)
we could argue all day about coding conventions but, guess what, there is no right and there is no wrong, there is just consistency that matters
You can use naughty attributes for inline inspector
Or just subclass selector
Then you don't need to make assets
anyways thanks a lot for your suggestion @kindred tusk and thanks for validation @upbeat path
https://assetstore.unity.com/packages/tools/utilities/naughtyattributes-129996
and
https://github.com/mackysoft/Unity-SerializeReferenceExtensions
right? need to understand these
Use the NaughtyAttributes from Denis Rizov on your next project. Find this utility tool & more on the Unity Asset Store.
https://github.com/dbrizov/NaughtyAttributes
Check the expandable attribute
Sorry it's obscenely late for me, I need to sleep
Good luck
vertx has a nice SerializeReference package too, but makysoft is legit aswell
Hello everyone!
I'm trying to figure out a way to detect objects within a certain shape. I've researched/used various collision detection methods, like triggerEnter/Stay, overlapShpere and overlapBox (onCollisionEnter/Stay does not work for me since I don't want to use unity's physics engine for my colliders. I want the colliders to detect, not interact).
Anyway, I'm leaning towards an overlapSphere/Box system, because it's what's closest to the way I want things to work, but I have a couple problems with it.
-
Problem 1: I want to detect positions in 3D space, but ignoring the y axis, so no matter if u are jumping or on the ground the game should recognize the collision based on x and z.
-
Problem 2: I don't always want the check to be a box, and because of the problem mentioned above, never a sphere.
-
Problem 3 (very tied to problem 2): I want to be able to use custom shapes, for example detect in a "Triangular Prism" shape, or a rectangle.
I have considered a very basic solution, but I really dislike it:
Use an overlapBox where the bounds are set to the maximum bounds of whatever shape I want, and with a comically large height. Then, from the gameObjects that exist in the overlapBox, check each one and determine if they exist within my custom shape, done by code.
I really dislike this since it's a very hacky solution, but I've not been able to figure out something better yet.
My ideal situation would be to create a gizmoz tool that allows me to add verteces and create a shape (kind of how a line renderer works) directly in the editor, and then to be able to read this shape in the code and use it to detect every gameObject in it. Any ideas?
So basically mesh colliders but never move them from the y axis
or you mean the collider can be a box shape but you want to check if collided object is of shape circle which is just a type check
I've thought about mesh colliders, but then I'd have to use triggerStay, when all of my actions essentially need to check the colliders at a certain point. I'm aware that I can save the intersecting colliders and act on them only when I need to, but I really don't want to check for them every frame since I don't need it.
And no, I don't care about the collider object's shape. Her's a sinple drawing, where 1 would be the overlapBox, and 2 would be the actual hitbox I want. The overlapBox would give me objects 3 and 4,and I'd have to loop through them to check if they exist within my "custom shape".
This already comes with a set of compromises, for example the fact that I'd have to set the overlap box to a very high heit to have a way to "ignore" the y axis, but it would also mean that the object exact position would have to be inside my custom shape, and not their collider, which is a box, or sphere, not a point.
My question exactly, is basically, Is there a method, custom or native, that works like overlapBox, but that allows for a custom shape?
every fixedUptdate rathern than frame*
Little sleepy to read these requirements, but seems like just a lot of calculating if a shape fits in another shape after doing calculating distances and rotations. As for the y axis problem I'd assume you can just leave everything not moving from y as y =1, disjointing the visible objects from the colliders.
i will just say that i know a lot more about this than you, it's not strictly about quality but about eliminating the sources of bugs. "buffering" as you call it, frame by frame, is achieving almost the same exact thing as reencoding to the format i'm talking about, except in runtime instead of ahead of time.
My question exactly, is basically, Is there a method, custom or native, that works like overlapBox, but that allows for a custom shape?
approximate the shaep you need using the overlaps. there are approaches that can do this. you can download an asset from the asset store which can create multiple-box-collider approximations of mesh colliders, then use it for overlap box invocations instead.
I'm trying to figure out a way to detect objects within a certain shape.
but this is a different problem.
what is the purpose of all of this?
it sounds like you are building a 3d platformer game, like super mario galaxy, and you want to design regions of the level where there are certain effects on the character? can you give me an example of why it's essential that these regions be highly accurate?
Hi,
I don't see how these are different problems, my goal is to detect colliders inside a custom shape instead of a box or sphere. And no, it's not a 3D platformer, it's a MOBA style game. So hitboxes can adopt varius shapes, but they need to ignore the Y axis.
In the time since I've posted this I've figured out a way to accomplish this, I'm creating a custom 3D collider script that allows me to define a shape using gizmos and a number of points, however I've decided to have only triangle and square shapes. I'm going to use various square/rectangle shapes to create custom hitboxes, same for the tringles.
As for how it's working, I'm going to implement the detection of both shapes with the overlapBox, and in the case it's a triangle I'll check if the object is within an "internal" triangle (see the paint above). This will defiently fit my needs, and even if it's not a native feature, it won't really be that distant from using a normal overlapBox, just with easier customization.
I'm aware I'm terrible at explaining myself...
Anyway, thanks for trying to help! I really do appreciate it
i'm asking what is the gameplay purpose
i know what a MOBA is, so just answer succinctly how you would use this custom shape detection
i'm not asking how it works. here's an example answer: "i want a way to design areas of the map that slow down movement, make your character hidden" or "i want a way to design AoE regions"
anyway MOBAs have really really specific traditions, it's kind of like movement code in CSGO. the implementation and the player experience are very tightly coupled, because everyone who plays your game will have played LoL, and it works a very specific, glitchful way in LoL so those same behaviors have to exist in you game. my suggestion is to research how league does it
yep league is about 0% transparent on how their code works, very understandable since 99% of it is pure garbaje. So yeah, if u are familiar with league, imagine a cone shape ability (panthone e, yone w, etc etc). That kind of detection where you need to know what is inside this cone at exactly the time that is casted, not have it constatly check enemies for when and if it's casted.
But as I said, I'm already working on the implementation explained above, If you have a better sugestion I'm all ears
okay. i mean so far you haven't specified the gameplay from your game that you are trying to implement. you still haven't answered the question. just writing it down will help a lot. you're giving a very abstract example, and i haven't played league in a decade.
you are saying cone, but i don't think you mean the 3d object called a cone. you are using gamer jargon for a programming problem
so part of the journey of doing this well is purging your head of crushed in head drooling guy gamer words
it sounds like your answer to researching how league does it is, "i don't want to"
for example, did you try googling "league of legends simulator" or "league of legends advanced rulebook AoE"?
matrix= Matrix4x4.TRS(someTransform.localPosition),someTransfom.localRotation),Vector3.one).inverse;
``` Is this the same as doing someTransform.localToWorldMatrix ?
.inverse would be worldToLocal.
Matrix4x4.TRS gives you the equivalent to localToWorldMatrix
Ok, now I'm confused. I'm trying to get some code from Valve, part of their interaction system to work with a full body avatar. At one point they do this piece of code
// get the desired pose of the wrist in world space. Can't get the wrist bone transform, as this is affected by the resulting physics.
wristToRoot = Matrix4x4.TRS(ProcessPos(wristBone, hand.skeleton.GetBone(wristBone).localPosition),
ProcessRot(wristBone, hand.skeleton.GetBone(wristBone).localRotation),
Vector3.one).inverse;
rootToArmature = Matrix4x4.TRS(ProcessPos(rootBone, hand.skeleton.GetBone(rootBone).localPosition),
ProcessRot(rootBone, hand.skeleton.GetBone(rootBone).localRotation),
Vector3.one).inverse;
wristToArmature = (wristToRoot * rootToArmature).inverse;
// step up through virtual transform hierarchy and into world space
targetPosition = transform.TransformPoint(wristToArmature.MultiplyPoint3x4(Vector3.zero));
targetRotation = transform.rotation * wristToArmature.GetRotation();```
jesus crsit u are the most ridiculous person in this fucking discord. I've been playing nice but you are just a grade A asshole. If you have not played league in a decade don't say u are familiar with it. YES, by a cone I do mean a triangle prism u failed abortion, wasn't that clear enough? I've also told u league is not transparent about their code, specially since they don't even use a game engine for the game so whatever they use is not applicable. Just because u fail to understand or grasp the concepts I've put down here does not mean it's because I've used "gamer jargon" for refering to a triangular hitbox as a fucking cone.
"it sounds like your answer to researching how league does it is, "i don't want to"" Srsly? man get fucking lost
So by the end what does wristToArmature matrix do ?
Wrist is a child of root and root is a child of armature, so it's going up the chain.
I believe the final .inverse on wristToArmature is reversing it back to local to world.
sorry, i'm not trying to be annoying. it's just important to use the right words for things if you want to succeed in doing this. it sounds like you only need 2d shapes. you can check out the methods in python's shapely project. here was how i did this research: https://chat.openai.com/share/8f2b53e2-f7e1-49d4-aaa4-47bed6844025
while i don't think there's one kind of personality that is "better" for programming than another, usually the people calling others failed abortions on the internet do not thrive at this.
Usually the people impersonating helpers that don't understand the question and intead of saying "Sorry, I don't understand" they imply that the one asking the questions is a moron, don't succeed ether.
If you are here to just pass the time and make others loose their time with your usless answers and mockings about their questions just leave, no one wants that
this is the hierarchy that works. transform in the code I shared is the RightHandObject. So A Vector3.Zero is being transformed by the wristToArmature matrix and then into local space of the RightHand Object, and that is my targetPosition..... , however the hierarchy of the full body avatar is totaly different obviously, since it is a humanoid. So how do I mitigate this ?
Sorry for the others but this dude is really in the code-advanced chat without any programing knowledge and just trolling.
What is the hierarchy you're working with then? Are there more bones in between?
Yes its a normal humanoid hierarchy
So something like wrist -> elbow -> shoulder -> spine?
Yep spine1 spine2 etc
Are you under the same restriction as this comment from Valve described?
Can't get the wrist bone transform, as this is affected by the resulting physics.
As in, do you only know the local position of the wrist relative to its parent bone?
You can't get the world position of the wrist easily?
I suppose I am, since I'm using their SkeletonBehaviour to drive the finger bones. But i just god the idea to spawn their skeleton as is, not render their hand and manually drive my bones from the positions of their bones.
Is anyone practical with Pushdown Automata/FSM and ScritableObjects? I have done some weird refactoring and I'd like some feedback. But will move in a thread
Then it doesn't seem like you need to do anything with the root and armature bones. If you need to translate all the finger bones over to a different armature, you could either just copy the local positions directly if the number of bones match. If they don't match, then it becomes a bit more difficult.
Looking for help with the Unity Player Accounts system as the code shown in the examples is outdated
https://docs.unity.com/ugs/en-us/manual/authentication/manual/unity-player-accounts
Using that code is not possible. They tell me to subscribe to a event but the method used to do it does not exist nor does the PlayerAccountsService Class
If anyone can take a look at this delirious stuff
Would love it
@pulsar crane Don't insult people. If you don't want to interact with someone asked them not to, ignore or block them.
man, don't cross post
I've got a simple test class, derived from ScriptableObject. ```public class NewSO : ScriptableObject
{
public string someData;
public NewSO(string someData)
{
this.someData = someData;
}
[UnityEditor.MenuItem("MyMenu/Do Something")]
static public void TryNew()
{
NewSO so = new NewSO("stuff");
Debug.Log("is null:" + (so == null).ToString());
Debug.Log("contains string:"+ so.someData);
UnityEditor.AssetDatabase.CreateAsset(so, "Assets/testNewSO.asset");
}
}``` For YEARS, I thought we could NOT create an SO derived object using "new", but this code works, it even saves the SO I created properly. I DO get a warning, but it SEEMS to work despite that. Whats going on? Did something change?
Does it work in a build?
unknown, I know I can't SAVE it in a build (wont have AssetDatabase) but I can check those logs I guess. will test and let you know
which Unity Version?
2021.3.15f1
interesting, I've seen something similar with EditorWindows, seems to start working in late 2020 but by 2022 it stops again
hmm.. I've got a 2022 version installed. gonna test it in there
last tested 2022.3.11, it was not working then
same output in 2022.3.0 (in-editor test only- still)
What's a good way to apply multiple languages to your game?
Unity Localization package, can be installed from the Package Manager
yes! same output in player.log
is null:False
contains string:stuff```
this only works because you are not relying on any of the messages that unity sends to SOs such as Awake, OnEnable, and OnDestroy
this also means it being a ScriptableObject is not necessary
makes sense- but it does seem to have one advantage over non-SO's : I can create an asset (and potentially change it's data in the editor) that I can reference in say.. a monobehavior with simple drag & drop.
how is that gonna solve the problem of it straight up not playing video back? I get that it reduces the need for inter frames and everything but how can I guarantee it's a reliable solution considering it doesnt seem to be something unity dev's wouldve made sense to optimise for
if i understand correctly, it appears that videos do not play at all when using what you believed to be an ordinary/logical workflow
i'm not sure what you mean by buffering frames, it sounds like you are blitting the video to a texture, then putting that texture on a material and using that instead
so to start, it sounds like you did not correctly set up using videos at all when orchestrating the videos using the timeline based on whatever unity documentation you read
is that correct?
are you asking me if I set it up wrong? lmfao
i dont knoiw
pretty sure I didn't
because it worked sometimes
its just like
so the ffmpeg for unity asset store thing I used has a GetNextFrame() feature
the "VideoTexture" you can just manually step through the video
which returns a Texture2D?
so i just use Graphics.CopyTexture or whatever it is
to a render texture?
and buffer exactly all the frames i need into a list
which I then display based on where the playhead is
its a really primitive solution
but all I needed was something that functioned
right
well i think you've sorted this all out
when I edited this message
i shouldve edited the last message I sent too lmao sorry
Hi all.
I've got a problem with the assembly stripper after updating my Unity editor version. Suddenly it began to strip out one of my assemblies and the error log helped me with that:
Fatal error in Unity CIL Linker
Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'SuperSocket.ClientEngine, Version=0.10.0.0, Culture=neutral, PublicKeyToken=null'
Now I added my link.xml file to include:
<linker>
<assembly fullname="SuperSocket.ClientEngine" preserve="all"/>
<assembly fullname="SuperSocket.ClientEngine.Core" preserve="all"/> <-- somehow the name of the lib doesn't match the namespace so I added both
</linker>
but now I get again an UnityLinker exception, but this time just a null reference without any information where to search for. Anyone a suggestion?
C:\Program Files\Unity\Hub\Editor\2022.3.11f1\Editor\Data\il2cpp\build\deploy\UnityLinker.exe
@Library\Bee\artifacts\rsp\348909197340592883.rsp
Fatal error in Unity CIL Linker
System.NullReferenceException: Object reference not set to an instance of an object.
at Mono.Linker.Steps.MarkStep.ProcessModuleType(AssemblyDefinition assembly)
at Mono.Linker.Steps.MarkStep.MarkAssembly(AssemblyDefinition assembly)
...
Try deleting your library folder (within the project) and reopening the project again
Thanks for the suggestion. It was something different though:
The error is actually the "wrong" name of the assembly as it seems. While the assembly name is SuperSocket.ClientEngine the file name had the .Core suffix. It seems like the linker was searching for the assembly file with a matching name and couldn't find it. So without the link.xml it was throwing the assembly out completely as it couldn't find the SuperSocket.ClientEngine.dll assembly (due to the suffix of the file name) and with the link.xml it was complaining that was able to find the file, but it was not matching the namespace.
Sounds weird, especially as it was working in former editor versions and I wish the linker would have given out a better explanation instead of just throwing out a null reference exception 🤷
which DI is better? zenject or vcontainer | I mean medium volume project
Does anyone know the best/most easy way to create a game that is compatible for both regular 3D PC players and also VR?
Is it even possible to do this easily? Or, should I just create 2 builds for the game, one for PC and one for VR?
This question is mainly about singleplayer games, but I would be interested to know how easy/possible it is to make a cross-platform game for XR and PC
All you have to do is build player rigs / control schemes for the two different playstyles
Then just instantiate the correct one based on the chosen mode
From a game design perspective it's not necessarily simple but from a code / architecture perspective it is.
Sounds similar to what I was thinking. Any way to automatically detect the player mode?
I'm sure there is but honestly I think it would be a better user experience if you didn't.
Maybe show the option for VR controls only if a VR device is plugged in but give the player the option of what they want to use between the two
Good ideas. Thanks a lot.
I haven't actually tried anything yet, but does anyone have a solid way of "parenting" rigidbodies without physx constraints/joints?
Like a jet landing on an aircraft carrier, or something
If you want things to still be simulated physically but like "inside a snowglobe", the best approach is to use multiple physics scenes
that still sounds really janky
it depends exactly what you're looking for
if you want it to just be solidly "parented" like a Transform parent relationship, you can get that if you make the child kinematic
nah it needs to be actively simulated.
Some guy on the forums made a post about this, and he tried just mimicing the velocity and other things
and couldn't get it to work
unity's implementation of physx is very strange altogether
like if you set the position/rotation of a sleeping body, it will automatically wake it up and add velocity
even if the position offset is just + new Vector3(0,0,0)
If the objects are physically touching and both moving via physics then I think this approach would be flawed from the start. Like the example you said, jet on an aircraft carrier, the "parenting" would happen when the jet is touching the top of the carrier. The carrier moving would cause friction on the jet, and any rotations wouldnt make sense to mimic directly unless the plane was exactly on the center
as far as I've tested, rigidbodies resting on rigidbodies doesn't work properly
in terms of parenting
maybe my tests were flawed
like if you move the bottom body, the top one just stays in place
Friction should be slightly affecting it, which you would probably want to set to 0 if mimicing velocity. The only issue I see would be that you constantly need to assign the velocity of the top body which might mess with collisions that happen
Rotations would also definitely be an issue
If I have a height map for a terrain, that has full position values, how can I calculate normals the right way? I'm trying this to calculate each normal but I get black squares at the edges because it has the incorrect normal
Vertex v = vertices[i];
int x = i%Resolution;
int y = i/Resolution;
var posA = position(x-1, y);
var posB = position(x+1, y);
var posC = position(x, y-1);
var posD = position(x, y+1);
var centerPos = v.position;
var normalA = cross(posC - centerPos, posA - centerPos);
var normalB = cross(posD - centerPos, posB - centerPos);
v.normal = normalize(normalA + normalB);
vertices[i] = v;
I'm checking out the 2D Bone animation stuff and it seems to force using PSB files. I was hoping I could swap out the textures during runtime for the individual sprites that are generated. But, it doesn't seem like you can modify the sprites or texture unless the actual PSB file is updated? Unless I'm missing something.
Since this is just happening in the corners, I'm a bit suspicious of your -1 and +1 indices. Are you sure these aren't going negative into values that don't exist?
Please don't cross-post.
The correct channel was the one you posted in first
mb cuzzo
I'm clamping it to the valid range
But maybe instead i could discard them?
Seems that by checking both ways, it does the fix
Vertex v = vertices[i];
int x = i%Resolution;
int y = i/Resolution;
var posA = position(x-1, y);
var posB = position(x+1, y);
var posC = position(x, y-1);
var posD = position(x, y+1);
var centerPos = v.position;
var normalA = cross(posC - centerPos, posA - centerPos);
var normalB = cross(posD - centerPos, posB - centerPos);
var normalC = cross(posB - centerPos, posC - centerPos);
var normalD = cross(posA - centerPos, posD - centerPos);
v.normal = normalize(normalD+normalC+normalA+normalB);
vertices[i] = v;
Hello, i have a problem with a variable that reset every frame with the value that was set in start() (stay at false) but there is no line where i set this variable to false i checked with ctrl + f and its a private variable. the code contain with the monobehaviour class, an editor class.
im kind of new with the custom inspector and i hope it isnt something in it that mess it up
Not an advanced issue, but remove all other debug.logs and replace the isMovingNow definition with this and show what it prints:
private bool _isMovingNow;
private bool isMovingNow
{
get => _isMovingNow;
set
{
if (_isMovingNow == value)
{
return;
}
Debug.Log($"isMovingNow in {name} is being changed from {_isMovingNow} to {value}");
_isMovingNow = value;
}
}
Ok, next add Debug.Log($"{name} Start runs"); in the Start method
so the script is on multiple objects
yeah
Then it works as expected? Changing the variable in one object won't change it in others
nop the code in update still doesnt run
doesnt get past the condition if (isMovingNow)
i put back the debug.log in the update still output false after the interact() call
Did you have it print the name of the object?
Hi, im trying to move froma compute buffer to a texture. When reading from the compute buffer at each index, i get this kind of distribution of values, but when doing from a texture they are more like this. What could be the reason?
Is it a two dimensional texture? If so, what code are you using to convert the index into X and Y?
The original values are float from -170 to 720, to map them to the texture i get them to the range of 0 to 1, and then lerp it from -170 to 720
This is the generation of the value for the texture
float4 a = new float4(v.v0.position.y, v.v1.position.y,v.v2.position.y,v.v3.position.y);
a -= minMaxValue.x;
a /= (minMaxValue.y-minMaxValue.x);
basically the transformation to the range of 0 to 1
and then, from index to X and Y i do
originally, to calculate the right index i did
uint x = index%_TotalInstances;
uint y = floor(index/_TotalInstances);
float2 fractalIndex = uint2(x,y)/(float)_TotalInstances;
int2 floorIndex = (int2)floor(fractalIndex *(_Resolution));
int index = floorIndex.x+floorIndex.y*(_Resolution+1),
That was to map the index from the instances uv space, to the world uv and then multiply by the resoltion to get the specific index
now, I just use floordIndex as the UV directly
Have you try to check what happens when you convert the index ? This code is really suspicious given your issue.
So the data is two dimensional and that's why you want to move from compute buffer to Texture2D?
the original data is a flattened two dimensional array
and then what do you mean?
if I use index on the compute buffer I get the first picture, if I use the floorIndex directly into the texture i get the second picture
My idea was that maybe the range of values wasn't fully transfered for some reason, and lost precision, but I dont think im in such a big range or if I have any option to disable compression or something
Because the values on the texture are like floored (im only interested in Y values)
(but im not flooring anything on the final result)
Test it instead of assuming it works
Yeah no, I just dont understand what do you want me to test
The conversion
yeah, the pictures is what i get
What format is the texture?
RGBA32
That's a very small precision format, only 8 bits per channel, or 256 possible values.
Ah then it's that, how can I get more precision?
That is not testing... Testing would be to isolate the issue and try to figure out if it works. Test it on CPU
Im sorry, but im literally lost on what are you asking. Test to use the index and see what range of values I get on the compute buffer and on the texture?
How many channels do you need? You can pick a float format that is signed and unnormalized. Then you won't have to do any remapping.
i need the four channels because im storing the normal map on the other three channels
(and the same issue is there)
for(int i = -170; i < 720; ++i)
{
for(int j = -170; j < 720; ++j)
{
(float, float) convertedFloat = ConvertToFloat(i, j);
(int, int) index = ConvertToInt(convertedFloat.Item1, convertedFloat.Item2);
Assert.IsTrue(i == index.Item1 && j == index.Item2);
}
}
Test to see if your code correctly translates an index to the correct X and Y position, preferably by having another function that does the reverse to see if the index remains the same. It's not really possible to test this in the shader, so that's why it's easier to move the code to script where you can debug.
Ah nono, but that's not what im doing. The remap of -170 to 720 is done by lerp(-170, 720, heightValue) and the height value is the value sampled or retrived from the compute buffer
It is not important how you are doing it, just test it to see if it actually works.
The index goes from 0 to 255 on the compute buffer and the texture
Okay, im gonna test that, it has been always working. The first image is the intended result btw, i don't want them to be flattened following the terrain just yet
There are many different formats you can choose from. This is the whole list, but not all formats will be supported on all devices:
https://docs.unity3d.com/ScriptReference/Experimental.Rendering.GraphicsFormat.html
Basically, you pick how many channels you want, how many bits per channel, whether it's signed or unsigned, whether it's integer or float and whether it's normalized (0-1 float) or not.
You can also use the simpler RenderTextureFormat enum, with fewer options. RenderTextureFormat.ARGBFloat appears to be 32-bit floats per channel, signed and unnormalized.
But uses 4 times more memory than RGBA32.
But im guessing that in any case, if I want more precision I will need more memory
Of course
Which format of Color do I need to use for RGBAFloat?
For RGBA32 i was using Color32
but using the same one it gives me the error of not enough data
Color would match.
Are you okay with the memory though?
Well, previously i was creating a compute buffer to store the same values, so the memory stays the same
I just save some time when sampling, altough I have to check now if there's any improvement and decide
But now I can save on instructions in general, since I can do bilinear sampling directly to the texture and not manually
Hi Editor Script: I want to store a number of changes in a component on the Undo stack - ah I have to call Undo.RecordObject on every component changed? This is tedious, hmm
windows kinect sdk help
So, Im not sure what its happening. How does Bilinear Sampling work= If I have a texture that is 3x3
.---.---.
.---.---.
.---.---.
like this, and I sample at (.5,.5) shouldn't I have the same value with both, point sample and bilinear sampling?
you are missing a lot of basic unity knowledge
In order to get around the common issues with standard singletons in Unity, I tried a hybrid approach of making a Monobehavior Manager a singleton, but rather than use a static instance for access elsewhere, it registers itself with a ServiceDirectory in it's awake. The Service Directory stores a references to the object, one for each interface it implements. Other scripts that want to use the singleton have to provide an interface to the ServiceDirectory and they get the object as that interface. I break up managers into multiple interfaces based on access level, i.e ITimeManager, ITimeEvents so that say things that just need read only access, don't get all the setters too. I've added extension methods for easily getting a services with as simple a command as GetService(out _audioManager). Does this seem like an effective pattern or overly complex?
Does someone have used firebase anytime?... Cause i have one error message and it's being quite difficult for me to solve it
This is close to the pattern I use, but I don't necessarily see why the managers need different interfaces?
I make my singleton a singleton, instantiate itself if it doesn't exist, put it in a DDOL parent in the loading scene, and then provide public static methods to everything inside it to reduce the boilerplate (like, everything that plays an audio clip just does AudioManager.PlayClip(clipEnum) instead of neeting to get the service directory, and ask it for an IAudioManager and then play the clip). I have lots of UI that .. just needs to play audio
i get this both logs when i import the analytics package from the SDK that google provides me... and i 've just selected it for android... not IOS
That is a reasonable take on it. I went that route as when I was doing my research the big counter to Singletons was that it makes all public parts of the manager available to anything that needs to use it anywhere. So a UI button could change the sound settings, or a label that is supposed to just get a read only value, could also set it. So the idea was to provide interfaces with limited access, to get it more in line with S.O.L.I.D design principles
Yeah - I mean, you do what works best for you. Some people want to do the DI thing in Unity for singletons/services but I've found in history, I haven't ever (or very rarely) needed to swap out an "actual" implementation with a test implementation for the interface. I also just generally strive towards as little boilerplate as possible for doing things when I can.
I tend to hide things that .. need to be hidden... behind a well defined interface layer to the singleton itself.
So all the state and race conditions and stuff like that is handled by the singleton (versus each consumer of the API needing to be concerned with any of that)
(ie - note private int _idSequence)
In this game, lots of things can create new tiles .. things that have short lifetimes and the GameManager doesn't need to track them, but the id on those items does need to be unique, so I centralized it here, and basically anything can just use this to get the next id: public int NextIdSequence => _idSequence++;
install ios module for your version of Unity, even if you won't be using it or are not on ios. That's the easiest solution
im working with serialization and i left my pc on over night which i sometimes do, it went into standby mode. ive come back turned it on from sleep and run the code then im getting a system.io error 112 for some reason when running the code again today. literally nothing has changed since then. its only writing 8kb a time also and thats also still being written. ive checked two drives (one ssd one hdd), both had space and im still getting the error. its bizarre. ive also tried shutting the pc down to no avail
A quick google says your hard drive is full, or the disk is corrupt, or windows/temp is full
hard disk shows space available
Depends on what you're doing in your code, but potentially leaving open file handles
Is windows/temp full?
You might have a billion small files .. I'm not an expert but there's something about small files taking up all the space in the file allocation tables
interesting!
Probably check through the windows error check stuff.. but this is beyond the scope of unity (probably not even really a c# thing):
appreciate the help rn, i dont get it because the 8kb files are still being written
post your code perhaps
Something else I saw says that the path might be too long
if you're writing that many 8kb i suspect you're putting them in nested folders with long path names
oh thats the thing, im only writing to a single file, the 8kb is a header thats written before
that writes fine initially, then the rest of the code which tries to divide up the byte[]'s and write their offset into the header
i did literally nothing and now it errors with the disk thing
oh, you probably have a bug there then .. why are you writing directly to the header?
the header is just 8kb of integers before the serialization starts
as a lookup table
bitpacking stuff
paste your code perhaps
there's so many questions.. like.. why not use messagepack or protobuf, or what are you trying to accomplish.. etc
yea u know how it is with the code, always the way
its nice to bounce off someone to help defrag the brein, so fank u for turning up
Hi , I have been working on a game with bought package and it used MVC pattern, state pattern , observer and injector stuff and mediator... I have understood how the code works but im having it difficult to keep track of how its all connected and when i wanna start making changes and implement my minds goes blank.. I hate this situation..idk how to go forward and learn efficiently and do what i want to implement
I wanna use all those concepts as my own
I'd go read on specifically on these patterns and try to piece together how each one would benefit in making your game. There's specific cases where some of these patterns could benefit your project more, so it's best to do research beforehand besides just looking at code.
A lot of these patterns are actually implied as you develop it all, and you may not even realize that you would be implementing them. It's more that the concept of game design and optimization utilizes a lot of them.
I see ok tnx I have understood and read about all the patterns.. seems what im lacking is beforehand research ..have to properly think and focus before implementing right?
yeah I noticed that too , it kind of really surprised my how all the concepts are used together
Think of systems for your game and which pattern would apply to it best. Some ideas would be the controls, movement, and animation. Object pooling and prefab/object assignment. UI interaction and updating.
Hey, dudes. I cannot find any setting to change control sort point for spine like what it exists in sprite renderer
My world is 3d and the characters are 2d.
I want they are sorted by pivot and not center
Hey, Im trying to save a RenderTexture
RenderTexture fog = player.FogOfWarTeam.currentFogTexture;
Texture2D newTexture = new(fog.width, fog.height);
AsyncGPUReadback.Request(fog, 0, (AsyncGPUReadbackRequest asyncAction) =>
{
newTexture.SetPixelData(asyncAction.GetData<byte>(), 0);
newTexture.Apply();
});
byte[] textureData = newTexture.EncodeToPNG();
System.IO.File.WriteAllBytes($"{_path}/fog.png", textureData);
and then im loading it like this
Graphics.Blit(fog.FogTexture, currentFogTexture);
but for some reason the loaded texture is just empty
Because you're not waiting for the asynchronous readback request to finish. Right after Request is called, it will start to encode newTexture, before the callback has been invoked.
ah, fair enough
If you don't need it to be asynchronous, you can use Texture2D.ReadPixels instead.
readpixels is too slow
I wouldn't expect AsyncGPUReadback to finish any quicker.
It just doesn't block the main thread, but will likely take a bit longer than ReadPixels.
what about Graphics.CopyTexture(fog, newTexture);
i guess movint it to GPU should be faster
CopyTexture only copies within GPU memory. That won't let you write it to a file.
so
var fog = player.FogOfWarTeam.currentFogTexture;
Texture2D newTexture = new(fog.width, fog.height);
Graphics.CopyTexture(fog, newTexture);
byte[] textureData = newTexture.EncodeToPNG();
System.IO.File.WriteAllBytes($"{_path}/fog.png", textureData);
wont work?
No. The delay can't be solved by using a different method. The problem is due to how game rendering works. When your script calls a method like CopyTexture, it's not telling the GPU right away to do that. It's adding it to a command queue, because the GPU is busy processing the command queue of the previous frame.
It can't copy it right away because it hasn't finished rendering the frame you're asking it to copy.
So the delay will depend on how long it takes for the GPU to finish all the rendering work already added to the queue, which is related to your framerate.
alright, so what can i do?
Are you sure you need the texture to be copied and written to a file as soon as your script tells it to, or is it okay if it takes ~0.1 seconds in the background, while your game continues running?
it is okay if it takes less than a second
Then you can continue to use AsyncGPUReadback, but fix the waiting, for example by moving the code into a coroutine and yielding the request before writing it to a file, or moving the EncodeToPNG and WriteAllBytes into the callback.
You do not need to call Apply btw. That's just uploading CPU texture data to the GPU so it can be rendered on screen.
alright, i will test it in a min
okay so the saved png is just empty
it weights like 190B
It doesn't look like you're ensuring that the texture formats between the fog RenderTexture and the new Texture2D match. SetPixelData is a raw binary copy, so the formats must be compatible.
okay so i guess i need to do something like
var fog = player.FogOfWarTeam.currentFogTexture;
Texture2D newTexture = new(fog.width, fog.height, fog.stencilFormat, );
but then what do i pass as a 4th argument?
its requesting some TextureCreationFlags
You can pass in the texture format of the Texture2D into AsyncGPUReadbackRequest to let it manage the automatic conversion.
Another option is to convert the NativeArray directly to PNG, without creating a Texture2D in between. You can use ImageConversion.EncodeNativeArrayToPNG for this. That might look like this:
RenderTexture fog = player.FogOfWarTeam.currentFogTexture;
AsyncGPUReadback.Request(fog, 0, (AsyncGPUReadbackRequest asyncAction) =>
{
NativeArray<byte> pngBytes = ImageConversion.EncodeNativeArrayToPNG(asyncAction.GetData<byte>(), fog.graphicsFormat, (uint)fog.width, (uint)fog.height);
System.IO.File.WriteAllBytes($"{_path}/fog.png", pngBytes.ToArray());
});
thanks, it works :)
Cool. Keep in mind that EncodeNativeArrayToPNG is thread safe, but you're calling it on the main thread currently. So the game will lag while Unity is creating the PNG, but it might be quick enough to not be noticeable.
why are you saving an image of the fog of war?
an HD image can take about 20ms to encode using the ImageConversion api, so you can't do it every frame on the main thread, unless you are okay with a 30 fps game
Who said that I'm doing it every frame? I want to save it when player quits the game
quits the game as in exits the application on windows? you can't reliably do stuff when the application exits on windows
so the purpose is to make a little screenshot for a save?
"Save & Quit" button.
the APIs for this stuff can be pretty cantankerous to use. you can try something like @unborn current
public async Task SaveAndQuit(RenderTexture fog, string path) {
var wrotePng = new TaskCompletionSource<bool>();
AsyncGPUReadback.Request(fog, 0, (AsyncGPUReadbackRequest asyncAction) =>
{
NativeArray<byte> pngBytes = ImageConversion.EncodeNativeArrayToPNG(asyncAction.GetData<byte>(), fog.graphicsFormat, (uint)fog.width, (uint)fog.height);
System.IO.File.WriteAllBytes($"{path}/fog.png", pngBytes.ToArray());
wrotePng.SetResult(true);
});
// this will allow you to wait for the thing to complete
await wrotePng.Task;
// now sequence the rest of the things you want to do
// or you can do them all simultaneously
}
But why would I use it when I already got a working solution?
Is there any case where
commandBuffer.CopyTexture could possibly set the destination texture to be null...?
i am trying to show you how you can do multiple things in SaveAndQuit in a coherent way
right now you have something of the form
void SaveAndQuitStep1() {
AsyncGPUReadback.Request(..., req => {
...
SaveAndQuitStep2();
});
}
void SaveAndQuitStep2() {
...
}
of course that works
but it can be really chaotic
and this is code-advanced not code-chaotic
with what i am showing you, you can do
await Task.WhenAll(pngSavingTask, gameSavingTask, ...);
so that things can happen as fast as possible
when they do not need to be sequenced
OR you can reinvent async/await over and over again
Usually you would wrap a callback based API, in this case AsyncGPUReadback.Request which accepts a callback with result AsyncGPUReadbackRequest, into a method that simply returns a Task<AsyncGPUReadbackRequest>, without further processing.
That way you can do:
var result = await TheWrappedAsyncGPUReadbackRequest(fog, 0);
// continue rest of the processing with pngBytes and saving
And the wrapped method is reusable.
on the same note as @undone coral, I'd also recommend using UniTask, https://github.com/Cysharp/UniTask
as it's a alloc free implementation of the c# Task class
is it possible to create custom conditional compilations?
Depend on what you mean.
well, you know how you have things like
#if UNITY_EDITOR
well i was hoping to simply make a different conditional to try to access a get; set; variable only if another script happened to be referenced into an instance.
problem is, since it's a public variable, simply waiting on awake, doesn't really keep the variable from checking itself.
also i should probably point out the variables im referencing is using Photon Fusion, a netplay solution.
since it doesn't impact my testing or gameplay whenever im in my level tester, i can settle for not worrying about the error
You can do #if ANYTHINGYOUWANT
https://hatebin.com/rerkktebep
Any suggestions on improvements on this graphic buffer class? It's unfortunate but I need to update them every frame with new transform positions, so I'm basically clearing and recreating numerous structs up to the buffer's capacity every update. Because the buffer works off the exact index of copied data, recreating a list of values does not work since I need that stride in between populated indices, and sometimes I may have no data set in between each index.
The usage of the class is for particles, and because I may have some with different lifespans, I can't exactly create a queue or stack but I don't believe I could use those anyhow.
I don't think these buffers accept nullable types anyway so maybe I'm stuck always creating up to the capacity.
How crazy would it sound to have like maybe 100 of these buffers with 50+ structs each being created each frame going off?