#archived-code-advanced
1 messages · Page 171 of 1
It works pretty well for me
I'm not sure that it's necessary since all I have to do is write something like this for new types of events
public IntGameEvent Event;
protected override GameEvent<int> GetEvent() {
return Event;
}
}```
but thank you
Yeah ultimately I wouldn't use code generation for this myself
Unity actually does support serializing generics (i.e., using GameEventListener<int> directly instead of a subclass) but I don't think that applies to storing them as assets currently
Generic serialization support was added in... 2020.1 I think
What do you mean by serializing generics in this context? My IntGameEventListener is a monobehaviour That I need to attach to gameobjects. It there a way to do that without creating IntGameEventListner and using the base class? (GameEventListner<int>)
Unfortunately it's not supported for MonoBehaviours or ScriptableObjects at the moment, just regular classes and structs
got it
So no, to my knowledge there is no way around this other than coming up with another design
It's just an unfortunate quirk of Unity
You may be able to use [SerializeReference]
That wouldn't work for a component unfortunately
UnityEngine.Object types are already serialized by reference
[SerializeReference] is for custom class types
Unity's whole serialization system is just a janky mess
Just do it like everyone else and make a nongeneric derived class like it has been suggested, this discussion is pointless
I don't think it's a pointless discussion -- imo that pattern sucks and we only really do it because Unity doesn't give us many alternatives
So it can be worthwhile to discuss other ways to approach the design
it has been discussed 1000 times, we don’t need to know you think it’s crap
Thank you for your input @compact ingot we definitely needed to know what you think of this discussion
My problem is solved for now. Thanks for the help guys
you are welcome
https://docs.unity3d.com/2021.2/Documentation/ScriptReference/Events.UnityEvent.RemoveListener.html
What don't the docs say what happens if the delegate is not attached to there?
What will happen tho?
mimics a real delegate
If it behaves like a regular C# event (i.e., Delegate.Remove) nothing should happen
Is there a way to check if the delegate is in the delegate queue?
I want to debug.assert that
That method doesn't even return true or false indicating whether it removed one or not
why does it matter
makes 0 sense
Normal C# delegates have GetInvocationList to allow you to do stuff like this
UnityEvent doesn't expose any public API for this, as far as I can tell
if you want to prevent doubling up you can remove-then-add
Okay so, UnityEventBase has an internal InvokableCallList field (m_Calls), gonna investigate what you can do with reflection here
No I just want to make sure with a debug assert that my program works correctly
Yeah, looking at this code it appears that if you remove a delegate that doesn't exist, it just ignores it. So it's at least consistent with expected C#/.NET behaviour
Here's the base code for UnityEvents
hi, i just finished writing the server and client code for a chess game, everything works fine except when I try to disconnect the client, I get the debug.log message but an error after it regarding the native list
Can anyone help me fixing the issue?
https://gist.github.com/Winter-r/1ed80c577fd9703660b71ebbba27caf4 here's the code
here's the error
you're trying to access a deallocated native list.
how can i fix the issue then?
also what differs a deallocated native list from just a native list?
hello?
You can think of "deallocated" like "deleted"
For all intents and purposes, the list no longer exists
You tried to access it after something deleted it
When I add a object to a list in a separate thread and then using it in the main thread the object is null! The Object is not null in the separate thread. Would love to get some help
Ok I fixed the problem by locking the list while modifying and using the list:)
you probably wanna use mirror
oh
nevermind
whats that?
you can use a different publish-subscribe approach if you need that
= roll my own custom thing?
no you can use UniRx
reactivex like the rest of the world
use a parent constraint for interactions like this
try using cinemachine for cameras if you need custom camera behavior
i think you meant uint instID = UNITY_GET_INSTANCE_ID(v)
but i don't think you're doing this right
you're supposed to use UNITY_TRANSFER_INSTANCE_ID
hey how bad of an idea is this
Don't cross post. Explain an actual problem
- Why even have a parameter if you just overwrite it in the first line of the method?
- Why would you ever pass a string around to represent a bool in code that isn't just a parser?
@somber zodiac Stop crossposting.
is it possible to get rid of this fog?
wrong channel
where should i put thist then?
its non active
im setting up a sort of lane-based card game and instead of coding each card individually id rather try and set up a string for setting the formula for each one in the prefab
it's plenty active and even if it wasn't you can't just post things in the wrong channel.
This is not the right way to go about that
You would do all your syntax-treeification up front
and that doesn't answer the question about why you have a useless parameter
because the string value in the function is part of an interface
Clearly a poorly designed one
yes
hi, I'd like to have a MeshRenderer masked by a SpriteMask. is there any way?
nope
ok so no way with custom shader or anything. just not possible. okay thanks 😢
I think you want a stencil shader
You can get a similar effect - just not with a SpriteMask as you asked
SpriteMasks pretty explicitly only mask sprites
ok I see. I'm making a custom particle system with persistent particles (using mesh renderer), so I wanted to mix it with masks
How do I make an object in URP render behind everything?
Realized it wouldn’t allow to get the other actual card so I changed it up to a more manageable script
Another poorly designed thing :hidethepain:
please rename your variables
Hey! So I'm trying to make a selection 3D "UI" that would allow the player to select one of multiple 3D GameObjects. It can have multiple options of a varying number. They will most likely always only one row horizontally but something more flexible than this could be nice. What are some of the more flexible ways to go about aligning them? The rest I can probably figure out!
You can use HorizontalLayoutGroup or GridLayoutGroup. I know these are billed as UI things but they can/do actually work with 3d objects as well
@sly grove ohh thanks, definitely thought theses weren't usable for 3D Objects, I'll look into it!
why do you abbreviate everything, its impossible to read
private float speed, newspeed, control;
private float drop = 0.0f;
private Vector2 vec;
private void ApplyFriction()
{
vec = new Vector2(_moveDirection.x, _moveDirection.z); // Equivalent to: VectorCopy();
speed = vec.magnitude;
speed = Mathf.Sqrt(_moveDirection.x * _moveDirection.x + _moveDirection.z * _moveDirection.z);
should I use vec.magnitude or just manually calculate the magnitude of the vector?
which one would be faster?
I assume that vec.magnitude runs faster since unity's vector is a struct and written in c++
it's a fair assumption that any optimization you can think of the unity devs also thought of when they wrote the .magnitude function in c++
Should be noted that there is no intrinsic reason that makes c++ code faster than c# code, they compile to the same instruction and both can be equally fast with c++ merely providing supremely dedicated programmes the opportunity to optimise a program a bit more for very particular use-cases.
you should use .magnitude
I want to automate my (development) build pipeline. It has to:
- Build and deploy the Windows Unity client. Don't care where it's deployed, so long as it's accessible by the team (I currently manually zip this and drop it in Google Drive, share the link to the team in Slack).
- Build and deploy a C# console app standalone to a VM in Azure (I currently copy and paste the files via RDP and restart the server myself). I need the ability to stop the running console app and start the new build.
- Build and deploy a Razor app to an azure App Service (no VM). I currently do this via the "publish" button in visual studio.
- Preferably notify the team via Slack (really nice would be an embedded link they could download the client with).
Any obvious candidate tools, aside from rolling my own batch file monstrosity?
github has something that can do this, yeah? Git Actions or something?
I mean you can definitely handle step 1 with UCB. I’m no help with the rest of the work, sounds like reason enough for a DevOps hire
Anybody know how to allow Reshade access to depth or normal buffer?
stuff you need to sort out for a build pipeline, with terminology so you can do some googling, plus a few common examples (also unity themselves provide some of these as hosted services):
- version control. this is git or perforce or whatever
- artifact store / artifact repository. this is where you put your built stuff. this is artifactory, github releases, s3 buckets, and yeah even google drive works, it has an api you can us for automation.
- ci server. this runs your builds and tests and other tasks. this is github actions, jenkins, circleci, etc. github actions are pretty nice and simple and might be the way to go, at least initially. jenkins is the super popular open source thing that has plugins for everything, but it can also be a gigantic pain to administrate and can get very complicated very fast if you're not careful. basically all of these tools support sending slack notifications and such.
- build scripts. this is a makefile, or batch files, or some shell scripts, or python scripts, or whatever. these are the glue you put in between all the other tools. these can turn into a real mess, keep them as simple and minimal as possible.
- containers (optional). if you're deploying any sort of game server or services, its really convenient to build them into containers. you do this with a dockerfile usually.
- infrastructure as code. this is for when you deploy stuff. terraform, ansible, puluumi, etc. you use these to deploy stuff and control state and configuration. this is what you'd use for deploying an app to a VM and automatically restart it.
i recommend reading the Continuous Delivery book (https://martinfowler.com/books/continuousDelivery.html) for general concepts, plus just doing whatever other reading you can on continuous integration, continuous delivery, build engineering, infrastructure automation, etc. just don't go any deeper than you really need to, it's a bottomless pit of complexity.
I use team city for this - easy to setup and free. It does exactly this in its dependencies and deployment steps. And has add-ons for unity now and slack. It also does multiplatform pretty easily.
I recommend you never do anything complicated in batch files or declarative config files. Always do scripts in a normal language. I like D for this, it's really convenient for scripts, the only problem with it is that if you need some specific API, you'll probably have to roll out your own thing, or link to C, there aren't enough maintained packages. Like, for example, if you need YouTube API, you'll probably have to work at a low level to integrate it, or link to C. Python sucks for scripts IMO, because the build process is not standardized and is usually super complicated, plus, I cannot take languages without static typing seriously.
Is there a way to add a button to my component editor in the inspector that would execute a certain method? Let me give you an example too
[InspectorFunction]
private void DeleteSaves()
{
foreach (var prefabInfo in _carPrefabInfos)
{
var displayInfo = prefabInfo.prefab.GetComponent<DisplayCarInfoComponent>().info;
var saveFileFullPath = GetFilePath(displayInfo.name);
if (File.Exists(saveFileFullPath))
File.Delete(saveFileFullPath);
}
}
And the prefab infos are assigned in the editor
so youd like to call this from editor by clicking a button?
so is this part of monobehaviour script?
yes
I guess I could do a custom editor and inspect the serialized properties there, but that's too much work
For something this simple
I guess I could do a context menu, that should work too
well that's what I was about to suggest. I don't know what would be simpler than that. if you call base.OnInspectorGUI, you don't need to reimplement the stuff you have so far, but you can just add new things on top of it (well underneath the deafult stuffs exactly as you want to)
context menu could work too but that would not be that fast to access
[ContextMenuItem("Delete Saves", nameof(DeleteSaves))]
[SerializeField] internal CarPrefabInfo[] _carPrefabInfos;
it would make more sense to have button there
Context menu item works for me
I'm using reflection to query attributes at runtime in my code. Specifically, I'm using RangeAttribute. I'm wondering if it will get stripped via this mechanism https://docs.unity3d.com/Manual/ManagedCodeStripping.html
Ultimately, I'm planning to generate code to replace reflection anyway, I'm just curious
It'd be nice if Unity made TypeCache available at runtime
and I believe trimming will remove the attributes yeah, though you can tell the trimmer to preserve them
For stuff like RuntimeInitializeOnLoadAttribute Unity stores a list of them inside _Data/globalgamemanagers rather than discovering them at runtime, you can use a similar mechanism using TypeCache to get all the type and member paths during the build process
I did subclass InspectorNameAttribute which I'm also using, and I have applied UnityEngine.Scripting.PreserveAttribute to it, which should keep that one non-stripped. The problem with RangeAttribute is that they made it sealed
Attributes should be sealed whenever possible
If they're not sealed they come with performance penalties
I'll read on the TypeCache thing, thank you
If you want an example use case of TypeCache, I have one here: https://github.com/NewBloodInteractive/com.newblood.engine-internals/blob/main/Editor/EditorSymbols.cs#L82
TypeCache was added in Unity 2019.2, though it only supports getting attributes on methods there, support for fields was added in 2020.1
The editor caches the attributes and other information upon loading the DLLs, so it's nice and fast to access
So does this code essentially do manual linking for fields marked with EditorImportAttribute? Looks awful lol
Fields which are delegates
Yeah makes sense
I'd definitely do it with a code generator tho
Unity has internal callbacks (editor-only) you can listen to for when a component is created
A code generator can't help here
You could certainly use one, but it wouldn't make it more performant or convenient
Why not? Instead of marking each of the fields with that, you'd just have a static class marked with it, and then you'd generate code that would assign each of them
Each of the funtion pointers
That would be even slower since you still have to scan for all the attributes in order to generate the code to begin with
(delegates)
And then you generate code on top of that
I don't mean emitting IL
I know
And parsing with Roslyn is reasonably fast
Right but it'd just be pointless for this
Since it would be doing more work than it is currently
Even parsing everything every time from scratch is not that bad
This is code that runs in the editor during initialization, the code generator would need to run there too
Oh yeah right
But it'd basically be doing the exact same thing but instead of assigning the fields, it'd be generating code to do the same thing
Makes sense
So it's just adding overhead
But if this was something supported at runtime, yes, code generation could be useful
if you're fine with it running like a snail, then it's fine I guess...
well, he beats me
So is this code only runnable in the editor?
Yeah
right
It works because the editor ships with PDBs, so it has access to the symbols
I see
It's possible to support it for builds, you'd just need to load the player's PDB, get the function RVAs and store them somewhere (probably in a ScriptableObject)
Though the APIs I generally need to call with this system don't exist in the player
So I haven't had much reason to implement it yet
It could be useful for exposing the TypeTree API in the player though
Which is the internal C++ version of SerializedObject/SerializedProperty
I'm wondering whether it makes any sense to use UnityEvent with readonly structs. I bet is does boxing / copying anyway, I bet there is no way to force it to pass it by ref, and I'm pretty sure it's impossible to achieve even in C# with generics, unless you do extension methods for firing the callbacks, which UnityEvent afaik does not
I think in normal C# you can do Method(in struct input) which might make it work
No idea about UnityEvents though unfortunately
I'd need to see an example of what you mean
in T value will pass by readonly ref but it has implicit copying whenever you do something that could mutate the value
readonly struct SomeStruct is basically just equivalent to marking everything inside the struct as readonly (sorta like C++ const functions), so it avoids the copies
Unfortunately you can't subscribe this to an Action<struct>
public readonly struct CarStatsChangedEventInfo
{
public readonly CarProperties carProperties;
public readonly int statIndex;
public CarStatsChangedEventInfo(CarProperties carProperties, int statIndex)
{
this.carProperties = carProperties;
this.statIndex = statIndex;
}
}
[SerializeField] public UnityEvent<CarStatsChangedEventInfo> OnStatsChanged;
internal void TriggerStatsChangedEvent(int statChangedIndex = -1)
{
var info = new CarStatsChangedEventInfo(
carProperties: this,
statIndex: statChangedIndex);
OnStatsChanged.Invoke(info);
_currentIsDirty = true;
}
Yeah, you can't pass by ref in that example unfortunately
Well
As long as the values remain on the stack you could use pointers
Yeah pointers are great, but I think those will look too freakin ugly in C#
public unsafe readonly struct Pointer<T>
where T : unmanaged
{
public readonly T* Value;
public Pointer(T* value)
{
Value = value;
}
}
public UnityEvent<Pointer<CarStatsChangedEventInfo>> OnStatsChanged;
var info = new CarStatsChangedEvent(carProperties: this, statIndex: statChangedIndex);
OnStatsChanged?.Invoke(new Pointer<CarStatsChangedEvent>(&info));
Pointer<T> can alternatively be:
public unsafe readonly struct Pointer<T>
where T : unmanaged
{
public readonly T* Address;
public ref T Value => ref *Address;
public Pointer(T* value)
{
Address = value;
}
}
This is illegal 😀
Yeah I was thinking about making everything unsafe and passing pointers directly
But this way it's better, beacuse the unsafe doesn't spread
I agree
You have to use a Pointer<T> wrapper type if you want to use generics, since pointers can't be used as generic arguments
Oh
So it's less me trying to avoid unsafe, I'm just forced to 😄
right
If I could, I'd have just used UnityEvent<CarStatsChangedEventInfo*>
Which might actually be possible in .NET 7
As will UnityEvent<ref CarStatsChangedEventInfo>
I guess the best bet here is to generate a non-generic pointer wrapper for every type that I want to use
Is there a problem with it being generic?
So that you don't have to do info.Value.whatever but simply info.Whatever with a getter
It's too much noise basically
At best you could add implicit casts to Pointer<T> but then you lose the ref-ness
What for? I'd just take non-generic types in the events, it's totally fine
Yeah I'm just talking about if you stuck to Pointer<T>
When transparent structs get added to .NET it'll be less of a problem
Since you can mark Pointer<T> as being transparent to T*
And then you can indeed just do info.Whatever
or rather, info->Whatever
It's an unfortunate syntax inherited from C due to operator precedence
C# didn't really need to inherit it, I agree
Fun fact: if you define extension methods on pointers, you call them via value.X()
You can't define extension methods on pointers in C#, but you can write them in IL and C# supports using them
https://github.com/dotnet/csharplang/discussions/5367 I have a request here about relaxing that restriction
btw unmanaged
Doesn't it mean it cannot contains classes?
Is simply struct not going to work there?
where T : unmanaged
Cannot take the address of, get the size of, or declare a pointer to a managed type
Is there a way to get around this?
@final steeple
unmanaged means a struct that does not contain reference types or references
So yes, you can't use a class for a type parameter constrained that way
I can't even take the address of such a type
I've found this tho
Got an example?
You can kind of cheese it
That particular example uses marshaling
It copies and converts the data
Rather than being an actual reference
So
there is a way you can do this
but it's only safe if you are really careful to never give it a reference to something that isn't on the stack
so
var someClass = new ...();
that someClass variable is safe, but if it was a field in a class it's not safe
You need access to the System.Runtime.CompilerServices.Unsafe class for what I'm about to suggest, note
public readonly struct StackRef<T>
{
public readonly void* Address;
public ref T Value => ref Unsafe.AsRef<T>(Address);
public StackRef<T>(ref T value)
{
Address = Unsafe.AsPointer(ref value);
}
}
var value = new SomeClass();
InvokeEvent(new StackRef<SomeClass>(ref value));
The event can even do stackRef.Value = new SomeClass(); and it will overwrite the value in the variable too
How can i trigger an animation thats inside a .fbx file from a a certain point inside a script?
set up your animator state machine to transition to that particular animation based on some parameters and set those parameters
I did set up everything but i had problems accessing the animation clip from the script, but i had the wrong method, i took SetTrigger() but i was in need of Play()
I got warnings that the clips were not accessible with SetTrigger
using System.Runtime.CompilerServices;
public readonly unsafe ref struct StackRef<T>
{
public readonly void* Address;
public ref T Value => ref Unsafe.AsRef<T>(Address);
public StackRef(ref T value)
{
Address = Unsafe.AsPointer(ref value);
}
}
public class A
{
public int i;
}
public readonly struct Info
{
public readonly A a;
public Info(A a) { this.a = a; }
}
public class Program
{
public static void Main(string[] args)
{
var a = new A();
var info = new Info(a);
var stackRef = new StackRef<Info>(ref info);
stackRef.Value.a.i = 5;
System.Console.WriteLine(a.i);
}
}
@final steeple this prints 5 under .NET 6, haven't tried it under Unity, but it should work. Note that I'm taking the address of the struct, and I made the struct itself into a ref struct (I think Unity has that) so that it doesn't escape from the stack. I'm not misunderstaning it, right, this should work for structs too?
Yes, that will work for structs
And it'll work in Unity too (that StackRef is based on a type I have in one of my own internal libraries)
What do you think the performance implications of this would be?
It's about as fast as it can be
Like that being unsafe and the casting
Those casts are basically free
btw, the Unsafe class isn't available out of the box in Unity, since it's not part of .NET Standard 2.0 or 2.1
But you can get the package from NuGet and copy the DLL in
https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/ Just hit the Download package link and grab the dll (and the xml too) from lib/netstandard2.0/
(the nupkg file is just a zip file)
I’m working with a modding community, and due to limitations in asset ripping software not being capable of ripping scripts, there are a lot of things in our game that we’re unable to analyze in unity editor, which is causing some serious challenges with a few things
So what I’m trying to look into now, is there a way to serialize a gameObject hierarchy into a format which can be opened up by unity’s editor?
We work in a game that relies heavily on random generation to make levels, but when the game updates this random generation changes in a way that makes preserving custom levels impossible between updates
So what I’d like to do is export the entire level’s gameobject hierarchy into a serialized file which we would bypass level generation to load
Sure, there are plenty of approaches you can take to that
You can even just generate the YAML for a Unity scene yourself
Grab the Scene and call GetRootGameObjects(), from there you just need to handle the bookkeeping of assigning GUIDs and LocalFileIdentifiers to things as you generate the YAML
You'll also need to have a way to determine the GUIDs of components on each game object, so you'll need some external database of sorts that the generator loads
Alright, thanks a lot. I was having a difficult time finding any answers online, this is probably a very niche issue hahaha
For sure lol
I've had to study this stuff a lot because I work on an official modding SDK for a Unity game
In my case it's even more painful though because I have to actively work against Unity half the time, since the modding SDK tries to be as detached from Unity as possible
I’m probably not going to touch this for a little while, but when I do I’ll probably be back here with more detailed questions later. Just having a starting point for what to research here is extremely helpful though, so thanks
Sure thing, no problem
@maiden turtle I forgot to mention, for reference types you will also want to GC.KeepAlive them
So instead of:
// store from field to local so it's safe to get a stack ref
SomeClass local = field;
var stackRef = new StackRef<SomeClass>(ref local);
InvokeEvent(stackRef);
You want:
// store from field to local so it's safe to get a stack ref
SomeClass local = field;
var stackRef = new StackRef<SomeClass>(ref local);
InvokeEvent(stackRef);
GC.KeepAlive(local);
The GC is free to collect an object mid-method if nothing is referencing it
StackRef is not seen as a root because it just stores a void*, the GC doesn't track it
Oh you mean that
Mid-method collection won't happen in debug mode but it will in release
Well, I store the struct I want to pass on the stack
Yeah for structs (as long as they contain no reference type fields) it's fine
It's just classes you need to do it for
(and any class fields of a struct)
So what you're saying is that the temporary gets sort of inlined in release
And turns just into a pointer
Moreso that the GC will look at where in the method it is referenced
And after the last reference, it will consider it free for collection
oh yikes
As soon as a reference type is converted to an unmanaged pointer, it's invisible to the GC, so StackRef won't count as a root
Which is why you need to GC.KeepAlive the object
The example you posted earlier is actually safe without KeepAlive because you have a Console.WriteLine call at the end which keeps it alive
So what should I do with managed struct? Call keepalive for every managed field?
If the struct is unmanaged, it contains no reference type fields
So you don't need to do anything special
For a managed struct you need to keepalive the managed fields yeah
ok thanks
In .NET you can actually call KeepAlive on the struct itself and it will work (it's an intrinsic and no box will be created)
I can do that with another autogened helper
Not sure about Unity's Mono
Not everything here will apply to Mono, but the comment above KeepAlive in the source explains the gist: https://source.dot.net/#System.Private.CoreLib/src/System/GC.cs,238
It talks a lot about finalizers too but it applies to all objects, not just finalizable ones (finalizers are just an example of something that can go wrong)
I could do this with a using, actually, and a Dispose method. It's the most friendly way, I think
That will ensure things are kept alive, yeah
I don't think you need to even GC.KeepAlive anything when you do that
Keep in mind though that using expands to try/finally, which has a performance cost
Not a big enough cost to matter when you're just dispatching events though
It's more of a "try not to do that inside the body of a really performance-sensitive loop"
You might need to mark the Dispose method with [MethodImpl(MethodImplOptions.NoInlining)] though
No I thought about putting the keepalives in the dispose method
I'm not sure if it's necessary to do that since afaik the dispose call itself will keep the whole struct (and therefore its fields) alive
[MethodImpl(MethodImplOptions.NoInlining)]
public static void KeepAlive<T>(ref T value)
where T : struct
{
}
would also work
The GC will see that a ref to the struct was taken and thus the struct's fields will also be kept alive because the GC has to assume that they're also needed
(Strictly speaking, it doesn't need to even take a ref, passing by value would also work, but for a large struct it'd be less efficient)
Yeah thanks, I'll figure it out now for sure when I do this.
Np
(And just to make it extra clear: NoInlining is needed since KeepAlive could get inlined and since it doesn't actually do anything, it would no longer keep anything alive because there is no longer any call being made. That's why even GC.KeepAlive is marked NoInlining, so that it still works even on a runtime that doesn't have intrinsic knowledge about the function)
Yeah I undertand that
A Dispose method that does GC.KeepAlive calls would work though of course, it's just extra work since you need to generate it
Just dumping as much info as I can lmao
But yeah, I think that's basically all that would need to be considered in order to use StackRef safely
Essentially, I will need this struct only to dispatch the event, so I could just generate a wrapper that would take the UnityEvent and call Invoke, with all that keepalive business hidden within
It being such a dangerous type is why I don't include it in my public libraries
One of these days I should write a Roslyn analyzer that catches unsafe usages of it, then I'd be more comfortable making it a public API
Shouldn't be too hard, just look for constructor calls and verify that the ref is on the stack or originates from a pointer
Properly catching cases where KeepAlive is needed would be a bit harder, but not impossible
or internal yeah
Luckily it being a ref struct protects against the other problems
So as long as the API that hands out the StackRef values does the right thing, it should be safe
Well, I bet I would've never encountered this problem myself in production. I tend to avoid heap allocating temporary objects, because why
Never -> small chance
It's actually not as big a deal in .NET compared to Unity
Unity just has an awful allocator, GC and JIT 😔
Does anyone know how to parse this data in Unity? {"-MxA4Cq7qTGhQRWmqhOB":{"icon":127,"pos":{"x":0,"y":0,"z":0},"ring":-1},"-MxA4TC-ro6SdVLCFzWs":{"icon":62,"pos":{"x":0,"y":0,"z":0},"ring":-1},"-MxA5CJcA64oxVlPbJ1I":{"icon":131,"pos":{"x":0,"y":0,"z":0},"ring":-1},"-MxA5W5FSSZjy8OVdXrb":{"icon":22,"pos":{"x":0,"y":0,"z":0},"ring":-1},"-MxAHQ2sxth8ia7lDsxc":{"icon":75,"pos":{"x":0,"y":0,"z":0},"ring":-1}}
If you plan to allocate these, you will likely need to pool them anyway
It's json
Yes, but how to parse it in Unity? JsonUtility doesn't like it because it's multiple children.
Oh and here are the actual stack ref types I use: https://gist.github.com/DaZombieKiller/777c2ce29c98c48fcf125eca0838c04b (minus the namespace lol)
People usually use Newtonsoft for this
Had to go hunting to grab those
you'll need a Json lib that is capable of parsing dictionaries for this
At least I feellike that one's the most popular
JsonUtility is extremely limited, it's basically only useful for really simple serialization (or when you need to serialize a native object in the editor)
Any suggestions on a full featured package? There's a lot of options out there and it's hard to tell what's good.
@quartz stratus @jade rivet @maiden turtle Thanks for the responses above (re: CI). For what it's worth, I already have version control (github) in place with workflow (gitflow) for branch management; but the rest is all manual (artifact repo, builds, and virtualization). I'm not going to build to containers right now - I think that's more complexity than I want to bite off, since the server itself is pretty simple - just requires dotnet 6. I'll look into TeamCity as well - although an early review of Github Actions seems really promising, especially since there's some unity client build support via "gameci".
You'll want to use Newtonsoft.Json as suggested above, or System.Text.Json
Note that the latter currently has issues with IL2CPP, but Unity has a fix on the way for that last I heard
System.Text.Json is going to be the fastest if your input comes in the form of UTF-8 text
Newtonsoft.Json is otherwise a solid bet and is a proven library
I tried using this: https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347 But there's no documentation at all.
look for newtonsoft json for unity on github
I would not use asset store packages for this
jillejr owns it
Json.NET is a popular high-performance JSON framework for .NET
You can download the assemblies from here and place them in your project
Note to this, only the one in package manager work with il2cpp
The one in the package manager is also very outdated
And was only really intended for use internally at Unity
If some one can try help me Ty:)
https://discord.com/channels/489222168727519232/948593127999033364
I recommend this:
https://github.com/jilleJr/Newtonsoft.Json-for-Unity
@final steeple the standard Unity System.Text doesn't support Span<T> does it?
oh, good to know that
Should I place my question in #archived-networking ? Sorry if it’s in the wrong spot
That's likely a better spot yeah
Simply because it's a specialized channel so people with specific knowledge will hang out there
Thanks
I'm getting a conflict with "com.unity.nuget.newtonsoft-json": "2.0.0", which I don't see in the package manager.
it's being transitively included from one of the other packages
I often have that issue - and have to remove my manually installed newtonsoft
the bright side is you can just use it from there without any installation
you are discouraged from using the manual version anyway since newtonsoft is now integrated into unity by default
They did finally start recommend it officially, a recent development. It has new update as well, on the next page. https://forum.unity.com/threads/conflict-between-assets-newtonsoft-and-packagemanagers-newtonsoft.843898/#post-7865422
but i'm glad they'll be switching to System.Text.Json in the future
That's great to hear. I was always turned off by Newtonsoft Json Unity Package 2.0.2 documentation that states, "This is a package intended for internal Unity Development Projects and as such this package is not supported. Use at your own risk." https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@2.0/manual/index.html
Hey guys
I'm tryna make a dynamic level selector, that automatically counts how many levels exist inside a folder. Do you know how I could count that through script?
A folder on your filesystem?
If yes, you can use the Directory.GetDirectories method that returns an array of the directories at the specified path. You can then get its length.
This will still work after build right?
Given that the path exists, yes
Because the player won't have the same file structure
It's up to you to determine the path you want to feed to GetDirectories. As long as it's valid and it exists, it won't throw
So let's say I wanna go to Assets/Scenes/Levels
Well, that's inside a Unity project files
That folder does exist on my machine, but when I send it to someone who doesn't have the project, but only the build, it won't exist
Addressables or asset bundles in general are how you can solve this if you don't want to make your own level format, yes
@final steeple So this is what is usually done in bigger games with lots of levels?
I mean, I don't suppose they have a fixed "NumberOfAllLevels" variable somewhere
For games that support DLC or need to download content (eg, mobile games) yeah
pfff I've been messing with addressables and it's so hard to understand
everyone talks about optimization
But this is not what I care about
Addressables is quite a complex system, yeah
I'd recommend reading up on asset bundles and getting the hang of them first
Addressables is basically an extension of that
do you anticipate giving others your source project to build levels in unity?
if levels are text files, it's fine to read them from a folder
if you don't need to deserialize to a typed object, simplejson is fine.
normally JSON serialized stuff has a corresponding class / model, especially if it comes from e.g. a tile map editor
I just manually convert it to the class.
yeah that's sort of your prerogative
I couldn't make it work the other way.
you probably want to use newtonsoft json and resolve your issue
you probably just laready have a newtonsoft json dll in your assets directory somewhere
but if manually assigning fields is fine just roll with it, this stuff doesn't really matter 🙂
Yeah, it works well enough.
newtonsoft json dlls conflict with Unity on newer versions because they decided to include it inside unity
is there a way to make an empty ui gameobject which triggers EventSystem.IsPointerOverGameObject because i need to "blackout" an area of the mobile screen to make the joystick usable. otherwise ass soon as the player slips over the joystick with the finger the game is gonna trigger a tap. I already tried to make empty buttons with Event triggers on them but they just dont count.
@lapis arch if all your levels will be baked into the game at runtime, there's nothing stopping you from indexing all of the levels when building using a build preprocessor
can create a scriptable object that just contains a list of levels
add an iamge to the button with a color of fully transparent
np
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
public static class PInvoke
{
[DllImport("user32", ExactSpelling = true)]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32", ExactSpelling = true)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("gdi32", ExactSpelling = true)]
public static extern uint GetPixel(IntPtr hdc, int x, int y);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte GetRValue(uint rgb) => (byte)((ushort)rgb & 0xFF);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte GetGValue(uint rgb) => (byte)((ushort)(rgb >> 8) & 0xFF);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte GetBValue(uint rgb) => (byte)((ushort)(rgb >> 16) & 0xFF);
}
@final steeple can you point me to the resources you found this/learn more about how to use it?
Like, is this just a boilerplate script or should I know how to make this lol
So, say I want to shoot an object to the right with x speed (in 2D). right vector 2 * the speed. Now say I want to shoot it in the same speed, but at a different aimed direction. How do I get that vector2?
ie, the object is rotated and I want to shoot it in the "forward" direction according to the rotation
dont think this is an advanced topic
Dam
@regal olive also I would ask for help with a script you're trying to make not just asking for one.
last time you posted code it was absolutely filled with syntax errors
you've also crossposted across 3 different channels after vertx told you not to
I feel like there's an easy solution to my question, I just can't seem to find it on my own.
Well, usually, you have a gun & bullet spawn. So the rotation of the gun is handled one place, then the bullet spawns at the guns transform.forward
@valid flame I’m stupid lol that’s why I need help
:AZCat_spincolorsfast:
Dam my nitro is gone
you should learn c# first
That's still not a #archived-code-advanced question. That's a 'take a tutorial first' answer.
I’ve took so many tutorials
and definitely shouldn't be in this channel
there's not a single opening bracket in that screen shot
The fun thing? I'm not trying to fire a projectile (yet, but I will at some point so that's still good info), I'm making a Sonic-like game and trying to make a dash move that dashes in the player's current direction when grounded. I'm using the Ge2D engine from the asset store as a base, so basic movement is in. I have a dash move in place, but it doesn't account for when the player is running up/down a wall, etc. That's what I need to know how to do.
Well when I tried to do it it wouldn’t work
I’m a bit I’m going to try again and I’ll see if I fix it
https://assetstore.unity.com/packages/templates/packs/ge2d-platform-runner-72278 this is what I'm using as a base, for reference
If it helps, there is transform.left but to get the other direction just multiply it by -1 transform.left * -1f;
Not C, C#
so sorry for your compiler
getting left is easy, I just use a vector2 from the Controller2D itself. The problem is that isn't accounting for angle changes, only which way the character is facing relative to their rotation (ie, like running on a ceiling to the right means the player is facing left in the game's logic, etc.)
Yeeeaaaah ^^'
the project isn't super far along that I wouldn't mind sharing the files for the purpose of figuring this out, if that would help
Expected: Color not always white
Actual: Color always white
Last time it worked: never
Tried: moving windows around, making sure nothing on my screen is white
private void SampleScreenColors()
{
uint[] rgbs = new uint[4];
for (int i = 0; i < rgbs.Length; i++)
{
rgbs[i] = PInvoke.GetPixel(PInvoke.GetDesktopWindow(), 500 + (i * 100), 500 + (i * 100));
}
for (int i = 0; i < rgbs.Length; i++)
{
colors[i].r = PInvoke.GetRValue(rgbs[i]);
colors[i].g = PInvoke.GetGValue(rgbs[i]);
colors[i].b = PInvoke.GetBValue(rgbs[i]);
}
for (int i = 0; i < colors.Length; i++)
{
Color color = colors[i];
color.a = 1;
}
}
I can post PInvoke if needed
Yeh but if I open Unity it'll just remind me I need to complete a bunch of work and I'll probably not be able to look at it for a week :(
hrm
maybe it just doesn't work outside of build?
I think my problem might be too specific for anyone to help..
except maybe @final steeple
I need to add a prefab to a script at runtime I'm placing this here because it is using photon
void Start()
{
GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
foreach(GameObject player in players)
{
if (photonView.IsMine)
{
this.playerCharacter.transform.position = player.transform.position;
break;
}
}
}
That's my code to get the player and attach it to the camera, but it's not working for me. Any ideas?
Are you meaning to check your own PhotonView or the player object's PhotonView?
Because right now it's checking the one on this script's GameObject
Yeah so I guess that's where I'm getting confused, maybe I'm overthinking it. I need to add the prefab player to the camera at runtime. Let me show the inspector
What's confusing you?
Also you're assigning the position in your code, not the player character reference
Which obviously won't work if the ref is starting as null
This kinda seems like a #💻┃code-beginner question TBH 😔
I mean kind of, but the Photon view has to be specific to the player that it gets
There is more than just grabbing the player which is why I placed it here.
It's a simple GetComponent call
Right, which isn't working for me at the moment.
Wait let me move the Get call
and try another way
Most likely you're just calling it on the wrong object.
You're currently looking at the wrong photon view so you're likely making a similar mistake with GetComponent
Been a long day lol, so maybe. I'm taking a look now
@sly grove I got it working, had to switch up some logic and move a couple things around. One thing was being called on the wrong object
Forgot to message back, figured I'd update at least lol
You passed the wrong pointer to GetPixel, it should be GetPixel(GetDC(GetDesktopWindow())) not GetPixel(GetDesktopWindow())
Generally you should write blittable P/Invokes but I don't know of a central resource to explain what that means
As for how I wrote that example, I looked at the documentation pages for those functions to see what their parameters were, and the Windows header files for GetRValue, GetGValue and GetBValue
it's already been solved sorry
If you want more information on writing P/Invokes I recommend joining the C# Discord and hopping into the #lowlevel channel, stuff like that is regularly covered there
https://discord.com/channels/489222168727519232/948779348465430528 I got help in this thread
I was actually really close to finding that out but I was like one mistake away
Works perfectly now
Nice
i think try search grep.app for the method names you are p/invoking
and find sample code
oh
it worked
nvm
I wouldn't recommend doing that, myself
A lot of people write really bad or wrong P/Invokes
So random sample code isn't super reliable to look through
I also recommend never going on the pinvoke.net site, almost everything on there is wrong or inefficient
I'm looking for a way to hook up to the build-process for Windows Standalone. I'd like to add a target in the Assembly-CSharp.csproj or add a .props file to the project but changes seem to get ignored and the file gets restored when opening the editor. I'd like to avoid having to export the VS project and doing it there. Is there a way?
are there any recommendation for software architecture specifically for ui frameworks?
There is MVC, MVP, MVVM, Layers, OOP in general, immediate mode GUI, retained mode GUI, DOM, Markup, Data Binding, Dependency Injection and others. It’s a rather large subject and depends a lot on your specific project. Often a specific framework combines multiple architecture styles.
Thanks for this list. I'm actually trying to find the right combinations of architecture styles to work with. We have this window based ui for our real-time 3d application (made in unity) and the current one we're only using is MVC whereas views are the ones attached to one UI (for example, an inspector tab). However, this rendered all developers to create each of their own handlers when selecting an object in the 3d scene (and some other things) and have seen a lot of repetitive codes around which rendered the already existing architecture useless or misused.
I'm thinking of a command based approach where when UI events are dispatch, we fire an event to execute a command that does a small thing (adding element to a list view for example) and can be reused in other ui windows.
however I kind of see it blowing up if we get into like, if we get a thousand specific commands to perform small tasks
then we're back to the same problem all over again
Sounds like you want to transition from MVC to MVP or MVVM to fix that. In any case you should separate data access from your views. MVVM (data binding) is probably what you are after with your ‘command’ pattern
afaik the msbuild projects only exist for tool integration, so I'm pretty sure you can't do that
moreover, msbuild is trash anyway, don't tie yourself to that
You can call the build from the console though, I've seen it done somewhere
wdym?
nvm, misread
It sounds like you might not be fully splitting data from rendering it (which I do advise), but otherwise what you propose here is basically how 'flux' inspired ui state management libs work. Look at Redux for the immutable functional version and Vuex for the mutation version to see how they handle it. It's simpler in unity though since a lot of the difficult stuff those frameworks have to reason about is 'when to rerender' and since unity is already rendering anyway, you might be able to skip a lot of that initially.
This is where the caveat about 'putting all your state one one big store' is bad goes, but I don't think it holds much water. Do it if it makes sense for your project. You will have a lot of 'commands', but redux also lets you build stores as 'modules' so that you can keep things more organized, which you could reproduce. Just remember that local state should also exist and makes more sense for some things, even if it's not your default. e.g. 'form' style interactions can be nice to encapsulate and submit when 'ready' rather than being data bound to the store itself.
If what you're building is less 'scattered views into some data' and more 'tree where siblings might want shared data' you can look at how react context works. The idea is to insert 'contexts' at different points in your tree and 'inject' their data into components beneath who request it. This pattern can be nice in unity because you can represent a context as a Monobehavior and just attach it to the parent at the point in the tree where that state should 'live'. Then you have something which keeps your contexts in sync once and your rendering code can read from each synced context accordingly.
Ah, believe me data is heavily spit with the views. The only concerning would be other developers handling those data and presenting it in the view (say a list of words to a text view). I have thought of doing a 'context' based approach like how android development would do it (can't quote me on this though because I can only vaguely remember it). Thank you for defining it as well, I do know that there's already tech that is similar, I just don't know what they are called. I believe handling ui in a functional sense is a brilliant idea, I'll look into those things that you mentioned.
As per the caveat of having many commands, we are basically making a runtime version of unity editor (I have seen some editor in the asset store and didn't quite like it). But then, I haven't really defined these 'commands' or even tried to abstract it. I just assumed that since we have a big scope, then it will correlates to how many commands we will need.
If your data is already split, it sounds like the first step is just an abstraction around 'reading data'. Either "Selectors" which take in some context (like a store or module) and return a subset of it, or some more kind of query builder. To me the start of solving a problem of 'devs are fetching the same data in different ways' should be 'make queries nameable, composable, and reusable'. From there it's much easier to cache or memoize them if repeated queries start to be an issue. First make sure they are all fetching the same thing in the same way, then optimize those cases.
for smaller projects I literally have a static class called Selectors which contains pure selector functions that take in the GameState and return some information
(but you could just as easily use extension methods or plain old methods on the state class for that if you wanted, since reading data is pretty safe)
also remember that you are using C#, so you can use partial classes and/or extension methods for organization
This is correct
If I store procedurally generated mesh data in a prefab, do instances of this prefab present in the scene add the size of this data to the scene size or do they just say "use what the prefab has"
the mesh data is a struct since unity doesn't serialise meshes in mesh filters/colliders when they're on prefabs
You need to show the code so we can see how it's being serialized, but from what I can tell, it sounds like your current setup will duplicate the memory in each instance yes
If you want to have shared data between objects you'll need to mess with [SerializeReference] or use a scriptable object
I've never heard of SerializeReference, interesting
its weird for it to duplicate the structures for each instance because they are all exact copies so I'd have assumed prefabs only store the changes
Structures are in-line in memory, it could not share them regardless
In the case of a Mesh reference it will share it, yes
Those arrays will be duplicated though
so if I have a script on my prefabs:
Quick question. Does MonoBehaviour come from the Mono Scripting Backend or am I just getting confused?
If you want to serialize a mesh as part of a prefab, it needs to be a sub-object
this will copy the SerialisableMesh for each identical instance?
That will share the references between the instances yeah
But then you need somewhere for that reference to exist to begin with
Which puts you back at square one where you wanted to embed a Mesh object
When you create the prefab you can do AssetDatabase.AddObjectToAsset(mesh, pathToPrefab)
ah, I assumed that when unity saves the scene, prefabs are just serialised as references + changes
my situation might make that difficult
If you have [SerializeField] Mesh someMesh;, that is treated as a reference to an existing mesh
So if the mesh isn't also stored as an asset like the prefab is, that reference will be lost
pretty much this is used for any part of my game where meshes are pre-generated in the editor, so for example destructible walls, procedurally generated fences/walls/roofs/etc, and so on. Sometimes they are unique objects saved as part of the scene and other times they are saved to prefabs for re-use.
so I should save the mesh as an asset?
Yes
As long as the mesh exists somewhere as an asset, the reference will save properly in the prefab
and instances will share it
okay, so now I need to figure out how to properly remove those assets once they are no longer being used
also I'm not sure if it's a good idea to store each mesh as an individual asset
since a single building might be composed of let's say 1000 chunks
That's why AddObjectToAsset exists
It stores it as an embedded asset within another asset
aah, I see
That's how, for example, an .fbx has materials, textures, etc contained in a single asset
so I'd have one asset for the building and all its generated meshes would be stored inside that
Yeah
Note that I'm not actually sure if prefabs can have sub-assets, so you may still need to store the meshes on something else
But either way, the only way to ensure the mesh is saved and stored is to keep it around as an asset
so the plan is:
-when a mesh is generated, use GetComponentInParent to figure out if we are part of a saved mesh collection or not
-if yes, make the collection get or create its asset and then add our mesh to it or replace the existing old mesh
-if not, add the saved mesh collection component to ourselves and do the same thing
Hey.
is there a way to export manifest.json file to custom .unitypackage package?
I am trying to create dependency to some UPM packages from .unitypackage .
I know I can link ProjectSettings files, but it seems I can't link manifest.json
That's what I'm trying to do. I'm working on a tool I'd like to set up during the build process and outside of the editor strictly speaking.
In my case I want to fetch the .pdbs after Unity is done doing it's thing and store them somewhere without having to spawn a new process from within the editor in some sort of build post process.
Unity doesn't use msbuild to build the thing tho
It just lists the files there
so that ides could work correctly
It has
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
at the end of the Assembly-CSharp.proj so I was thinking they were there for exactly that kind of stuff.
That's just part of the default csproj template
They have plans to switch to the new csproj format so maybe they'll finally use the proper .NET SDK stuff to build projects eventually
Here's where they discussed switching to modern csproj + msbuild: https://forum.unity.com/threads/unity-future-net-development-status.1092205/page-13#post-7923634
I'm really looking forward to that, the new csproj format is so nice to work with
having full control over the build will be a godsend
So, since my last question has been answered so fast, i'll try my next.
I have a problem with a compute shader. I want to model individual agents moving on paths, but everything just goes crazy and the objects are jumping all over the place.
The odd thing is, that i tested my logic already in C# (since debugger=love), translated it 1:1 twice and it works there flawlessly. So my guess is that the error is coming from somewhere else. My setup is this : I have Structs to manage the agent data. For the Path i have an edge array per agent that is flattened to it fits into a structuredbuffer (i tested the flattened accessing and writing as well) and (of course) on buffer to hold the original array lengths. My theory is that the buffers maybe mess with the order of its content. It sounds silly but i have no other explanation at the moment. Do you have any idea ? Code provided if needed.
That's some happy news together with some sad news.
your theory sounds right because if you translated it, the biggest difference will be the way data is structured and not the logic
are you doing something out of the literature?
No, or not as i know specificly
All kinds of things could be going wrong. First thing to do is double/triple check that the data marshalling between CPU/GPU world is perfect. Nothing causes chaotic results like some misaligned buffers
yeah
i mean it's not going to be out of order, but you will probably have an issue reading/writing them
also yeah you could still have a logic problem
some things are called X and really do Y
That sounds fun, i guess i will pasebin my code here so we talk about the same stuff.
hard to say though what moving on paths means without a specific algorithm to talk about though
that's why it will be sort of hard to look at your code and understand what's going on
are you just saying you are doing N tweens with time t and list of vertices Path
in a compute shader?
so Vector3 MoveOnPathPure(float time, float constantSpeed, List<Vector3> path)?
except, N invocations of that?
Yes the idea is the same.
The Shader Code : https://pastebin.com/UKqfGnM9
Shader managing code : https://pastebin.com/VWjHqBJA
But i am 99% percent sure that it is something with reading and writing the data, sice i tested the same code with a jobsystem (just replaced distance(a,b) to Vector3.Distance, normalize and float3 to Vector3)
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
To the marshalling suggestion, i am using
System.Runtime.InteropServices.Marshal.SizeOf(typeof(TC));
To get the size of by structs that i pass into the buffer
you need to show the C# structs too
Of course ! https://pastebin.com/PpNNLgfQ
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
You shouldn't use Marshal.SizeOf, it gives you the size of the struct when used for marshalling which isn't the same as the actual size of the struct
You can just use sizeof
In this particular case the marshalled size and the normal size should actually be equivalent, but it's something to keep in mind
Hmm, I don't see any obvious issues here, can you post the full C# code?
i will try sizeof asap - currently im not on my ide. i postet anything related to the shader
but thanks for the idea
I don't see the objectData field in that code
sizeof probably won't make a difference in this particular case
well if you want i can post all classes in full with base classes
Basically just seeing the full class for the example above should be enough I think
ok
So here are the shader calling classes : https://pastebin.com/jWDFqQeR
Static methods that call outwards are tested in other systems
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
If you constrain T to unmanaged, you can use sizeof(T) in an unsafe context
public abstract class HLSLSimulationRunner<T> : SimulationRunner
where T : unmanaged
{
// ...
}
Then you can initialize the ComputeBuffer like:
public unsafe virtual void Start()
{
shaderBuffer = new ComputeBuffer(objectAmount, sizeof(T));
// ...
}
Also you're just immediately querying the data in LateUpdate, there's no guarantee that the shader has actually finished running by that point
You need to use a graphics fence to ensure that it's done
that might be a thing
Is that true? I thought Dispatch was synchronous?
It is not synchronous, no
How do you wait then? I have a whole project where I'm assuming it's synchronous 😱 (which works fine 🤔 )
A graphics fence
Okay it appears I'm slightly mistaken -- Dispatch is not synchronous, but GetData will forcefully wait for completion
Oh in my project I don't ever read the data back. I just use it later in a shader
Yeah generally GetData shouldn't be used
Unfortunately I'm not experienced enough with compute shaders to really know what's going wrong here though
okay
@carmine agate so what i'm a little confused about is
can your cars change speed? can they change paths?
it sounds like you have something of the form
well
it's really complicated
can i see your C# version?
i think the error is probably in that you are holding onto state in your C# version that you're not communicating to the computebuffer
so the logic is indeed wrong
because what you're really trying to do - have a bunch of cars move around with possibly changing paths, and animate them frame by frame
is really complicated
creating a pure function for that is complicated
by the way, you're reinventing particles... i think you should just use VFX graph for this
but that could be even harder
this is super challenging
you can encode the path in the form
rows: vehicles
columns: zero zero zero, followed by a list of path position x, path position y, total time to arrive here
then generate a texture that is the gradient of those positions (i.e., "lerping")
rows: vehicles
columns: position at time v
then, the particle will sample its position with time = u on that texture, particle id = v on that texture
so for example, your path buffer
[0 0 0], [1 3 4]
[0 0 0], [3 2 2], [5 2 4]
two vehicles of differently length cycling paths? are they cycling? maybe not 0 0 0 then
then you'd get a gradient
[0,0,0] [.1,.3, .4] [.2, .3, .8] ... [1, 3 4] [1, 3 4] [1, 3 4]
[0,0,0] [.3, .2, .2] [.6, .4, .4] ... [5 2 4] [5 2 4] [5 2 4]
then sample it
going from the path encoding to the gradient is challenging
otherwise you should really find something in the literature / preexisting for this
because particles can already sample paths this way
you woul dhave to consult a shader cookbook @carmine agate
having this error cant find what i dit wrong
Wow, thats a long answer... no they do not change path. they have one path generated on start and then cycle through this
I can give you the c# implementation in a bit if you want also with the runner
the thing is, i want to compare different types of computation of an algorithm to each other, so monobehaviours vs jobs vs hlsl vs cuda vs .... so if i change the approach or model completely the comparison becomes obsulete. My other (simler) models work fine with this model - i hope cuda doesn't bitch as much around as the shader
the line number doesn't match with the code, so i guess you changed something
But maybe enemyManager.enemiesInTrigger is null or something
i see
do you have a research advisor?
yes but none with experience with shader code
But i guess i will wrap this up for today and get my head free maybe i will have a diferent idea tomorrow. Thanks for the effort, if you want i can keep you updated
sure, good luck!
thanks good evening for you
most likely the enemy is null from whatever enemyManager.enemiesInTrigger is
what is enemiesInTrigger and how is it populated?
so what is calling those methods?
the gun script
made in the gun script a public EnemyManager enemyManager;
so i can reach to EnemyManager
you should share the entire Gun class, see #854851968446365696 for how to correctly share code. because you haven't actually shown where those methods are being called
you spelled your OnTriggerEnter/Exit methods wrong
the only lines where those two methods are declared
yes
but how do i fix it if i take a look i wont see a problem
you need to spell it correctly. notice how your spelling doesn't quite match what i typed here #archived-code-advanced message
make sure VS Code is properly configured using the steps linked in #854851968446365696 so that it will autocomplete stuff like that so you don't misspell it again
VS Code doesn't autocorrect those method names, at least not with the default configuration
okay
does this error means that it is it cant find the object it is suppose to look for
when i press shoot button error only Occurss
If the code is the same as earlier, it means enemiesInTrigger has some empty slots
or destroyed gameobjects
show the Gun object's trigger collider since that is what determines which enemies are added to the list
Probably... it's your game
if you're following a tutorial, see what it does
looks like there are no enemies in that collider
hi guys, im going to have a json file that represents different stuff for my game for example..
"tiles": [
{
"id":"BAC5F3F9-9030-460A-B0E7-239387D4C7DB",
"tileName": "grass",
"movementSpeedFactor": 1.0
},
{
"id":"7B3D4075-D0E5-4C2B-9131-2825F701264A",
"tileName": "stone",
"movementSpeedFactor": 1.3
}
]
}```
a json that represents tiles and various stats about that... the tutorial i followed from what i could tell just had hard coded GUIDS, wondering what the best way the generate them and reference them would be? hoenstly probably could just no use them..
you can create guids using... new GUID
i don't know if you need them though
whoa, thats simple, i wonder what i was googling wrong..
yeah i agree, ill work without them for now and see how i go
thanks!
I need to cast a ray forward from the player. However, we are using no root animations so the transform.forward is always in 1 direction. How do I work around this?
public class LevelScriptableObjectEditor : Editor
{
public override void OnInspectorGUI(){
serializedObject.Update();
LevelScriptableObject levelScriptableObject = (LevelScriptableObject)target;
FloorScriptableObject[] floors = new FloorScriptableObject[levelScriptableObject.numOfFloors];
for (int floorIndex = 0;floorIndex<levelScriptableObject.numOfFloors;floorIndex++){
// Draw floor
GUILayout.Label("Floor "+(floorIndex+1).ToString("00"), new GUIStyle { fontStyle = FontStyle.Bold });
floors[floorIndex].tiles = new TileScriptableObject[levelScriptableObject.floorWidth,levelScriptableObject.floorHeight]; // Getting an error right here where it says Object reference not set to an instance of an object.
}
serializedObject.ApplyModifiedProperties();
}```
```[CreateAssetMenu(menuName = "Serializable Objects/Level")]
public class LevelScriptableObject : ScriptableObject
{
// [Header("Graphics")]
public Sprite floorTileSprite = null;
public Sprite wallTileSprite = null;
public int numOfFloors;
public int floorWidth;
public int floorHeight;
// [Header("Floors")]
public FloorScriptableObject[] floors;
}```
```public class FloorScriptableObject : ScriptableObject
{
public TileScriptableObject[,] tiles;
}```
```public class TileScriptableObject : ScriptableObject{
public ScriptableTileType tileType;
public Sprite tileSprite;
public bool isDoor;
}
public enum ScriptableTileType { Floor = 0, Wall = 1, Hole = 2, Door = 3 }
``` Trying to figure out why I'm getting an error at the floors[floorIndex].tiles line. Can anyone help me out?
it's telling you. the error is probably a null reference excpetion
it's null
i don't think you can serialize public TileScriptableObject[,] tiles;
what's your objective?
this stuff already exists
I'm trying to make a game with grid-based movement and small levels to be stored as data. I'm working on an editor to accomplish this.
unity can't serialize multidimensional arrays
so I need to make a tilerow class after all ...
have you narrowed down which variable is causing the null reference exception
@thin merlin you do not
you can encode a 2d array linearly
// create your 1d array:
TileScriptableObject[] tiles;
// to retrieve the tile at x, y
var tile = tiles[ y * gridWidth + x ];
for what I'm trying to accomplish, picture this. Now imagine each tile can be modified to have a different type. Optimally, you'd be able to click on the tile and have it pop open a small window where the tile's data can be edited, but I'm not sure how to do that yet
I'm picking up what you're putting down
you don't need a 2d array
and read this to help with your null reference issue: #💻┃code-beginner message
yeah, it's a case where I knew what the error was but the situation prevented me from getting a good grasp on the error
mk
Not sure if you found your solution, but what you can do is attach a game object to a part of the character controlled by animation (like the head or something on the head), then use global forward from that object to represent player forward for your raycast
what is global forward?
Not local
transform.forward
Yes.
awe ok
I know that because I was dealing with that, up, and right earlier 😛
So it needs to be on an animation part, got it. let me try this. Thanks
Because I have it as a child, but its not part of the animation body parts
It doesn’t matter if it is part of animation parts or not. Only thing that matters is the object that you are choosing is accurately “facing” the way you want to use as forward for your player facing direction.
I'll explain a bit more. So I'm using transform.forward for the direction of the ray and it seems to be casting it always in Vector3.forward direction. Then I looked at the player as I rotate him, the transform.forward is not rotating with the player.
The script is sitting on the player root?
The script is a child of the player GameObject
Ok, then create a game object to represent your forward anchor. Child that object to a part of your character that will visually face the direction you want your player forward to represent.
Create a reference field in your player script to that anchor.
Then use that anchorForward.transform.forward as your forward in your ray cast.
awe interesting ok thanks!
hi guys, not sure if this is advanced or not.. but im trying to associate tiles with some data... by adding them to a dictionary and i get this error.. ArgumentException: An item with the same key has already been added. Key: TX Tileset Grass 15 (UnityEngine.Tilemaps.Tile)
here is my code.. i think i need to break that inner for loop?
{
_dataFromTiles = new Dictionary<TileBase, Tile>();
var tiles = unitOfWork.Tiles.GetAll();
foreach (var pos in map.cellBounds.allPositionsWithin)
{
if (map.GetTile(pos) == null)
{
return;
}
foreach (var tileData in tiles)
{
if (map.GetTile(pos).name.Contains(tileData.tileName))
{
_dataFromTiles.Add(map.GetTile(pos), tileData);
}
}
}
}```
You know that different spots in your Tilemap that use the same tile will all return the same TileBase right?
So having a Dictionary<TileBase, Tile> is not going to work - it will only let you store one Tile reference per tile type in your tilemap
Dictionary<Vector2Int, Tile> would be more reasonable
sorry, how do i then get the tile? i dont think there is a gettile that returns a vector2 int?
its a vector3
possibly a Vector3Int because unity is funny like that
https://docs.unity3d.com/ScriptReference/Tilemaps.Tilemap.GetTile.html < this accepts a Vector3Int
so presumably you already have a Vector3Int
use that
(this is the hazard of using var everywhere - you have no idea what types your variables are)
just transform it into a vector2?
sorry was confused for a sec, got it all working, thank you!
@undone coral Good morning : I had a look at my shader code problem again and changed my logic to test if its that or something with the passing of the edges and i guess its that.
My new logic looks like this :
Edge edge = GetPathEdge(cars[id.x], cars[id.x].pathIndex);
cars[id.x].position = edge.from;
cars[id.x].pathIndex++;
if (cars[id.x].pathIndex >= pathLengths[cars[id.x].id])
cars[id.x].pathIndex = 0;
The result should be that each car jumps to the next path node each frame. Since i only assign passed positions of my edges the result should be that they stay on their paths. If the order is messed up they might jump across paths but should have a position on any path anyway. But my result is that they land on very odd locations that have nothing to do with any path positions. So the passed edges are completely wrong inside of the shader
quick question. What's the use of a first pass assembly script on unity? I read it can only communicate with other first pass scripts but whats the use for it?
It’s used to compile plugins that rarely change. So your overall build of project specific scripts will be faster. It is largely superseded by assembly definitions that allow you to create an arbitrary number of such separate assemblies.
alright, thanks
So I put a Grid Layout containing 3D Objects within a Scroll Rect. Nothing happens when I try to drag, what step am I missing?
(the viewport should read Collection Scroll)
I don't see how your scroll rect issue is even remotely related to code
More like #📲┃ui-ux really, don't you think?
Alright, will do, sorry!
probably pathIndex is from a car that's not cars[id.x]
Hey there! I have a question about architecture. I am using a system where i use the Animator state machine to transition between Idle, Move, Jump, Attack etc states and then handle the game logic of those states via the Built-in State Behavior scripts. Its a system i found out about via a tutorial online but it seems a bit fragile cause messing up the animator transitions slightly can break the entire project apart. Do you think a system like that can work or should i abandon it and try something else now that its still early in the project?
what kind of game is it?
Its a metroidvania type but its only the prototype so for the moment i plan on doing just one big level but i m trying to do it in a clean expandable manner in case i want to create a full game out of it
it will have chained combo attacks, movement skills etc
maybe study the moremountains corgi engine 2.5d asset
to see the scope of this
i do have the asset, but didnt want to use it for now cause i m still learning and feels like cheating myself
for a lot of metroidvania-style behaviors you are going to be controlling animations frame by frame in your own scripts
i m not sure how this works. For now i use a custom function to play most of the animations without using the mechanim system and use some transitions in the mechanim system for combo hits
do you have a link so i can check what do you mean by controllinmg them frame by frame?
it really depends on how traditional you want to get
there isn't really a link, but what i'm talking about is
Application.targetFrameRate = 60, and then in an Update you increment an integer and set the sprite renderer's sprite to the next image
because that's how SNES games work
i should mention its a 2.5d game cause i could find 3d assets easier
can i still do that in 3d?
like playing the next frame of the animation like that?
yeah, anything is possible. it really depends on what your goals are
personally i think writing things this way is really cantankerous, but personally i don't like metroidvania games
i don't find that kind of frame-by-frame gameplay interesting
so if someone put a gun to my head and said, make a platformer, i'd use corgi engine
and it wouldn't have a lot of those extremely nuanced hardcore metroidvania details
because i don't find them interesting at all
corgi engine already does everything except the super hardcore details
maybe you're not aware of them
well to be honest it has most features i would like to have in the game
there's stuff like, the exact frame of samus and the exact height needed on that particular frame to connect with an edge or whatever
to people who play these games, that stuff is really important
just like how people who are really into super smash play with a 20 year old controller
yeah i havent thought into that part
and talk about the exact frames and glitches and stuff
i guess you are right
well that's the biggest factor in the engineering
if those super hardcore details aren't important, you should definitely use the tools unity provides
for animation and such
cool so what i ll keep from this is to better check the corgi engine thoroughly first
and probably try to expand on that if i need specific things
yes, it already does "everything but the super hardcore metroidvania details"
cool thank you very much for the chat
How could I get the value of the enum selected in a dropdown to use as an argument for the GiveMaterialsFootstep function? Thanks!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(FootstepModifier))]
public class FootstepModifier : Editor
{
public GameObject WorldGameObject;
public List<Material> MaterialsForThisFootstep = new List<Material>();
public enum MaterialToUse{
Concrete = 0,
Wood = 11,
Metal = 26,
Grass = 7,
FallGrass = 31,
Bark = 8,
MinesDirt = 14,
Snow = 32,
Pillow = 3
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if(GUILayout.Button("Generate Footsteps For This Material"))
{
}
}
}
public class FootstepModifierFunctions: Editor
{
void GiveMaterialsFootsteps(GameObject WorldGO, List<Material> MaterialsForThisStep, ResultOfEnumDropdown?)
{
Renderer[] Mats = WorldGO.GetComponentsInChildren<Renderer>();
for(int I = 0; I < Mats.Length; I++)
{
for(int X = 0; I < MaterialsForThisStep.Count; I++)
{
if(Mats[I] == MaterialsForThisStep[X])
{
if(Mats[I].gameObject.GetComponent<GorillaSurfaceOverride>())
{
Mats[I].gameObject.GetComponent<GorillaSurfaceOverride>().overrideIndex = 2;
}
}
}
}
}
}
you can cast an enum to an int to retrieve that value
that you assign
Sorry I'm a bit new to lists and stuff. How would that work?
So just something like
(int)MaterialToUse?
maybe ask in #💻┃code-beginner
hmnmm how could i fix this
not an advanced issue, but you never define writer you only declare it
@ancient pilot Debugging guide is pinned in #💻┃code-beginner and ^^
thank you
tbh.. this is quite advanced for me.. cuz i havent worked with servers tillt his point
also from what i see, driver.BeginSend() doesn't have an output param but does return DataStreamWriter that was older documentation actually i was wrong
For the network related stuff you would have better chance getting an answer in #archived-networking
DataStreamWriter writer; ?
that's where it is being declared. it is supposed to be defined by the BeginSend method, but since it is returning null that means the connection is likely not successful. You'll probably want to print the value returned by BeginSend() so you know why it is erroring
you can change the BeginSend line to Error.StatusCode statusCode = (Error.StatusCode)driver.BeginSend(connection, out writer);
then when you print it you can compare it to the descriptions here to find out what is going wrong https://docs.unity3d.com/Packages/com.unity.transport@1.0/api/Unity.Networking.Transport.Error.StatusCode.html
This looks like the third manual for this thing and this one uses latest updated name for it I think https://docs-multiplayer.unity3d.com/transport/1.0.0/api/Unity.Networking.Transport.NetworkDriver.Concurrent/#beginsendnetworkconnection-out-datastreamwriter-int32
fixed the problem.. the problem was about writing the code inside a different class, so the class didnt work properly kekw
would be handy if I write code on the correct class
@ancient pilot Make sure you have intellisense installed ( #854851968446365696 ) That you should've had straight up warning for from IDE.
Hey, does anyone know if there is a way to determine if the accessor of a class field is outside the class or inside the class?
public class Test1
{
public float x;
public void Update()
{
x += 9; // INSIDE THE CLASS
}
}
public class Test2
{
public Test1 test1;
public void Update()
{
test1.x += 9; // OUTSIDE THE CLASS
}
}
I need to do this in code. I could explain why but that will make this too confusing for now, even for me.
Thanks
Also I am not sure if "accessor" is the right word. I just mean the scope maybe
no. but it's easy to enforce that code outside the class cannot access certain things, or ahs to access them through an intermediary such as a property
I am trying to make a system where when an object accesses its own data, it reads the actually data. But when object accesses another objects data, it reads a "copy" of the data.
This copy would be created at the start of each frame
My goal is to make a system where the programming stays the same in workflow but the result is that all the objects run code in parallel (sudo parallel)
so like if you have a(1) and b(0) and a looks at b and says if b is 0 than set myself to 0, and b looks at a and says if a is 1 then set myself to 1. Then when you run it, only a will switch
class Test {
private float real;
private float copy;
int lastFrameChecked;
public float TheData {
get {
if (Time.frameCount != lastFrameChecked) {
lastFrameChecked = Time.frameCount;
copy = real;
}
return copy;
}
set {
copy = value; // not sure if you want to allow this?
}
}
}```
something like this?
properties are your friend
not really clear on your goals here
so no thats not what I mean, and yes, properties are my friend, and thats where I am trying to get it to determin whos accesing it
you can't dettermine who is accessing it unless you force a parameter
private float x;
private float _x;
public float X
{
get
{
// I want in here to return x if accessor is this object and return _x if accessor is another object
return x;
}
set
{
x = value;
}
}
public float GetTheData(object source) {
if (source == this) return realData;
return copyOfData;
}``` something like this?
not possible
for real....
Why not just have the things access different properties/fields?
Are you talking about different instances of the same class reading each other's data? Or other code entirely?
for user experience and continuity reasons
Ill try to explain
@sly grove When working with simulations, you are at the will of the iteration loop. So if you have a list of 5 particles that all need to move according to the gravity felt by all the other particles, then after you update the first particles data in the loop, now every other particle is looking at different data from the start of the frame. X and Y are not the same anymore so the sim is lopsided.
To fix this we can introduce copies of the data from the beginning of the frame. So that you read from the copy but you write to the real one. This is pretty easy to do manually but I was trying to make it such that you only need to reference the "real" one and the system handles it.
HOWEVER, when I made this work in javascript, I realized that when and object accesses its OWN data, it needs to be the real one and not the copy. So that's where I am at.
I am confusing myself but I know that there is a route to what I want here and I am trying to find it. And if I can't then I will fall back onto just manually doing it. Say with a particle having and x and y field and also an x_copy and y_copy field
I mean the simple way to do this is just make it a two step operation.
This is the approach sebastian lague takes in his solar system video
enlighten me with this two step operation
but you essentially do:
foreach (body in allbodies) {
body.CalculateForcesThisFrame();
}
foreach body in allbodies) {
body.Move();
}```
Any way to get a position of contact from a OnTriggerStay?
nope your best bet is Collider.ClosestPoint or something like that
I recommend watching this video if you haven't https://www.youtube.com/watch?v=7axImc1sxa0
Experimenting with gravity and attempting to make a miniature, explorable solar system.
Watch the next solar system video here: https://youtu.be/lctXaT9pxA0
Project Files:
The Unity project is available on github here: https://github.com/SebLague/Solar-System/tree/Episode_01
If you'd like to support my work and get early access to new projects...
Oh yeah, thats sort of what I am talking about. Since when you call CalculateForces, you have to store the forces somewhere. A sudo copy. And lets say you have a lot of these two step moments, then its more beneficial to just have a copy of the data
I have watched it but thanks
Well you could store them all in an array, or in a field on each body
yeah thats what my fall back is. Thanks for trying to help
i love the soothing voice of sebastian
I've been at this for a few hours. The player has a small trigger in front of him to climb things. I need him to face directly at the climb object. The climb object uses a box collider. How can I get the player to face directly at the climb object that the trigger is hitting? Now picture the box as a wall, if I'm to the far left of the wall, using Lookat will face me at an angle on the wall cause the center of the wall is to the right. I need him to face directly at the wall at any position on the wall.
can anyone help me with my save and load system?
set the player's forward to the opposite of the wall's normal
🤯
in unity, could i visit each rigidbody and calculate net gravitational force pre fixed update, then add the force i store in fixed update?
is there a pre fixed update?
How do i write a code that selects 1 of 3 resources based on how much % of the overall resources it is?
like if i have very little of one resource it should have a higher chance to get selected so it evens out after time
i see
are you trying to emulate gravitational force?
@split sierra look up weighted random
wait nvm this wont work.
give lower % a higher weight
The box collider has 4 sides, I need you to face the side you are on.
there are a few approaches to that
to figure out what face of a collider you are closest to
you probably already have a raycast
so you already have the normal of the collider's face
the hit angle
you can project the hit vector onto xz, then player.transform.forward = -projectedVector
@river musk why wouldn't using the normal work
raycast to the wall, use the normal
it will change depending on the side of the wall you're on
whats the line of code for using the normal?
i know how to raycast, just show me the normal part
Raycast hit = /* ... do the raycast */
player.transform.forward = hit.normal;
you'll probably have to tweak it depending on how you want to rotate
awe interesting ok ill try this
but the normal is what you want
well i just want you to face the box on whatever side you are on
right, so I'm saying that if transform.forward doesn't give you the direction you want, you can tweak the final rotation by some amount to get it to be the right direction
ok thank you!
so for example
IEnumerator Start() {
while (Application.isPlaying) {
var forces = GetGravitationalForces( ... );
ApplyForces(forces);
yield return new WaitForFixedUpdate();
}
}
@sinful fossil why not just use x within the class and X everywhere else? You aren't required to use the property
if it doesn't have errors what's the issue
just wanted you to know it works perfectly now! Thank you!
woo
I know this isn't a Unity specific issue, but I'm grasping at straws here. So I'm hoping someone in this channel can help. Any idea what would cause the code below (in the red box) to execute just fine on a standard Windows OS machine, but not on a Windows OS machine that is set up to be a dedicated server (i.e. no GPU and no Direct X)? ...and yes, the Game.exe is built using Unity's Dedicated Server build options.
Since this isn't a Unity specific issues, I'd recommend either taking it to #497872469911404564 or the C# discord
Didn't know there was a C# Discord. 😲
there's no tty so redirect standard input could fail
also you have to start it with -nographics -batchmode etc
IL2CPP doesnt support System.Diagnostics.Process
It is a unity problem. Nothing wrong in Mono/.NET/C#
Try this. Should work on windows.
https://www.pinvoke.net/default.aspx/kernel32.createprocess
Hello, can someone help me with this. I updated my package manager despite Unity being in 2020. @ me with response please, thanks.
just saying, too many misleading usages of pinvoke on pinvoke.net... some still fine tho
: ()
@latent moss #📖┃code-of-conduct Use forums for job posts
ohh ok, i didnt know this, thank you 👍
This P/Invoke is incorrect and can lead to memory corruption because it marshals a normal string to lpCommandLine, which CreateProcess will mutate
pinvoke.net provide a correct p/invoke for once challenge (impossible)
public unsafe struct STARTUPINFOW
{
public uint cb;
public ushort* lpReserved;
public ushort* lpDesktop;
public ushort* lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public ushort wShowWindow;
public ushort cbReserved2;
public byte* lpReserved2;
public void* hStdInput;
public void* hStdOutput;
public void* hStdError;
}
public unsafe struct PROCESS_INFORMATION
{
public void* hProcess;
public void* hThread;
public uint dwProcessId;
public uint dwThreadId;
}
public static unsafe class PInvoke
{
[DllImport("kernel32", ExactSpelling = true, SetLastError = true)]
public static extern int CreateProcessW(ushort* lpApplicationName, ushort* lpCommandLine, void* lpProcessAttributes, void* lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, void* lpEnvironment, ushort* lpCurrentDirectory, STARTUPINFOW* lpStartupInfo, PROCESS_INFORMATION* lpProcessInformation);
}
// ...
STARTUPINFOW si = default;
PROCESS_INFORMATION pi = default;
fixed (char* pFileName = @"C:\...\Game.exe")
{
if (PInvoke.CreateProcessW((ushort*)pFileName, null, null, null, 0, 0, null, null, &si, &pi) == 0)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
}
You can use this
If you want to pass in command-line parameters, you need to allocate a mutable buffer to pass to CreateProcess:
STARTUPINFOW si = default;
PROCESS_INFORMATION pi = default;
fixed (char* pFileName = @"C:\...\Game.exe")
{
var pCommandLine = (ushort*)Marshal.StringToHGlobalUni(commandLine);
try
{
if (PInvoke.CreateProcessW((ushort*)pFileName, pCommandLine, null, null, 0, 0, null, null, &si, &pi) == 0)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
}
finally
{
Marshal.FreeHGlobal((IntPtr)pCommandLine);
}
}
(and of course, you need to enable unsafe code in your project settings or assembly definition)
string marshalling is not dangerous if handled properly in the native side, which windows obviously does
https://docs.microsoft.com/en-us/dotnet/framework/interop/specifying-a-character-set
It's not the string marshalling that is dangerous
It's the fact that it's being used on lpCommandLine
Even the P/Invoke for CreateProcess inside the runtime libraries does not marshal that, because it needs a pointer to mutable data
.NET strings are immutable
Even the Windows API documentation calls this out:
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
(and CreateProcessW is what will be resolved for CreateProcess in the majority of cases)
So basically, if you marshal a .NET string to it, it will receive a pointer to the string's data and potentially mutate it, corrupting that string in the eyes of the runtime
The same applies to the ANSI version CreateProcessA, but that one won't end up mutating the .NET string because the marshaller needs to allocate a new string buffer with the correct encoding, but CreateProcessA shouldn't really be used because it means your code won't support unicode paths
The P/Invoke on pinvoke.net uses CharSet.Auto so it will end up calling CreateProcessW and therefore corrupt the input string (if you pass it one for that parameter)
Just a bit more info to add to my wall of text lol: https://docs.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-for-strings#strings-used-in-platform-invoke
When the CharSet is Unicode or a string argument is explicitly marked as [MarshalAs(UnmanagedType.LPWSTR)] and the string is passed by value (not ref or out), the string is pinned and used directly by native code.
CharSet.Autois equivalent toCharSet.Unicodeon Windows, so it will indeed just pin the string and pass a pointer to its data to the function
I am trying to generate plant models using splines, however I can't figure out how to curve/position a spline based on a float/slider.
Basically I want to have a float value that determines how much a spline (leaf) curves/bends downwards or upwards. Another way to say it is how effective 'gravity' is on it.
I am also trying to figure out how to create a spiral of a spline.
As I expect the answer to be a longer one I am more looking for what to lookup since I just can't figure it out for this one.
you would have to modify the spline's control points based on those parameters. what exactly you have to do depends on how your generator is set up.
basically this, but in 3D. you may have bezier-splines, there the control points are a bit different, but the principle is the same.
Yeah I got that part, what I am unsure of is the math/logic to use to appropriately place them. I would also want to place the anchor point of one end of the spline as well as the control points.
its maybe most productive to play around with the control points / handles visually for a bit until you have some intuition for how the curve shape responds
approaching it from a math standpoint is just semi-helpful, in most cases the math behind them doesn't matter much and your handle positions are a very neat abstraction
there are some nice yt videos explaining the math and actual non-math origin of splines https://www.youtube.com/watch?v=pnYccz1Ha34
This video covers the basics of Bezier curves :
- Linear Bezier curves
- Quadratic Bezier curves
- Cubic Bezier curves
Twitter: https://twitter.com/GuidevOfficial
Sponsor:
For video games porting, optimization, and co-development please visit : https://pixelwings.co.uk/
Yeah, I understand the math behind them (lerping between the points). I guess I am more unsure of how to place the control points to get 'mathematically correct' curves if that makes sense.
you can only get piecewise polynomic curves with splines, they can never truly match anything that is non-polynomic, like a circle, sine curve or catenary, there will always be some error, but in practice (gamedev/design) that does not matter.
What I mean is the top one looks more 'right' than the bottom one
it will always be a judgmement call, you'll have to figure out how to mimic the "correct" curve with spline control points
That is what I was kind of asking of how to do 😛
But I guess I will just try messing around with it more, haha
do your splines have a visual editor?
if not, you can just use a vector drawing app
Yeah, I got Affinity Designer. But also I am using Unity's new Splines so yes either way haha
will the compiler pick the smallest possible underlying type for an enum? like i've been assuming they're int unless specified otherwise, and manually specifying them as byte or whatever depending on how many different values they hold and just realized that might be pointless
or i mean it's likely to be an unneeded optimization in any case since i'm not blasting through millions of them but just wondering
They are ints unless otherwise specified. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum
You are also correct that it's not likely to make a difference to make them smaller, unless you have very specific use cases where that's important
thanks, yeah, just one of those things that feels nice to do anyway
as long as it's at least technically doing something
Heh. While I appreciate all the input, especially the intriguing debate it spurred with @final steeple , @novel plinth , and @tough tulip ; but this isn't the cause of the issue. As I said, the application launches just fine on one system, but not on another.