#archived-code-advanced
1 messages ยท Page 183 of 1
So i feel kinda dumb because i couldnt figure out how to implement that list idea with each game object and then manipulate them. Seemed complicated but now this explanation is making me think thats the only way. What i did was make separate functions for each of the 4 references i needed individually and set them in the singleton so i could call them. It seemed to work as i can again see the references in the editor on scene reload
let move to #archived-code-general
code
async Task Start() swallows exceptions? How do I make the engine await the task?
that is insufficient to help you
what should I add
I saw async void Start() and kind of giggled at that, because I know it won't work, but async Task Start() does not work either?
imo declaring async unity callbacks works poorly
I have a problem, after instantiating a gameobject I cannot access jagged arrays for some reason. The arrays are created in the same script. It throws out a nullreference exception.
https://gdl.space/felegasuda.cs
@maiden turtle use unitask, and do
void Start() {
UniTask.Void(async () => { ... });
}
same as
void Start() {
InnerStart().Forget()
}
async UniTaskVoid InnerStart() {
...
}
unity's default async execution context is bad
and the rules for how it treats Start, OnEnable, etc. when they're declare async are fuzzily defined
It says neurons is null
so we need to see where you define and create neurons
ok
Ok thanks
but like its fine when I try to call it on a different line in the script
The size of the jagged array is supposed to be set in this function, sorry the thing that I posted first didnt make sense new link that has a similar error https://gdl.space/rowuciyefo.cs
public float[][] neurons; this is in neuralNetwork
ok, where do you create the array?
here
not sure how that's possible. it should work fine with git
Not in that code you do
?
I found out! Sorry! It was happening because the teammate that pulled didn't setup the addressables correctly
like not clicking the GenerateDefaults button lol
yeah
I create the sizes of the array here
it sounds like you guys are not using git right now
we are using perforce... I hate it btw lol
You create the sizes of the inner array (neurons[i])
you need to create neurons as well
ok found the error sorry
you can't use sizeof on a Vector3. users who want to manipulate raw memory, for the most part, of .net types should use the Marshal functions
No, quite the opposite actually
You should avoid Marshal when you can
You can sizeof a Vector3, it just requires unsafe context
Or you can use Unsafe.SizeOf which does the same thing
I forgot to move it initalli I had it in start and moved everything else and forgot this tysm for the help
Marshal.SizeOf will give you the marshalled size which is different
๐ #๐ปโcode-beginner next time
idk I thought it was some sort of weird error also ppl were talking there so I didnt want to annoy them
in code general too
I'd elaborate further but I'm on mobile currently so typing it all out would be hell -- but know that this guidance comes from Microsoft developers working on .NET itself
Much of Marshal is essentially "legacy" as far as modern code should be concerned
(like whole unity .net)
yeah definitely.
That contradicts what Zombie mentioned that it doesn't
This is very close to what is done yeah
It doesn't use much extra storage because of how and what we encode
We only need a single component per pixel, not full rgb
Because the color is defined by the light
Yeah that's the only thing I could think of
Really though that's the easy part -- the hard part is actually generating those lightmaps to begin with
Oh yeah
You need to do a lot of "deconstruction" on the textures
I don't even watn to get into that ๐
@final steeple you are making a lightmapper?
Not quite a lightmapper, just a system built on top of Unity's lightmappers
We can use enlighten, progressive, etc as a base
And we process their output into data that we use
i see, waiting for someone to make runtime lightmapper
(1) use [RuntimeInitializeOnLoad]. declare a private constructor. the rest you can fill in it. that's it.
(2) it sounds like you want to add an attribute to something. it's better to have the something strongly reference your code and invoke it every frame. otherwise, i suppose a regular list of weak references.
There's a few
i only seen native libs
I guess they might've quit after SRP
@proven thorn DOTS doesn't really work, so i wouldn't recommend trying to build a game on top of it right now
And if you aren't using DOTS, I have a guide on how to write a proper (imo) singleton for MonoBehaviours
runtime lightmapper, something simple Q1/3 style, for retro shooters, imagine that
I've looked into it -- for one of the games I work on we support loading Quake and Half-Life BSP, including lightmaps
the hardest part is computing the lightmaps at runtime. shipping a whole renderer for your game, then dealing with all of that, is a lot
So in theory if you wanted to do lightmapping at runtime you could run the BSP lightmapping tools externally
And then reload the map
yeah. i would ship blender, round trip the geometry with FBX
Blender might be a bit heavyweight but it's a step in the right direction yeah
I imagine the biggest problem might be licensing
nobody does that stuff
how to do weighted generation again? (with a ten percent chance, generate this)
and how do i do it with multiple outcomes? i know i could just generate a number between 0 and 1 and do the rest but what if i had for example:
outcome 1: 15% chance
outcome 2: 20% chance
outcome 3: 30% chance
outcome 4: 35% chance
yeah blender as a dependency is a no no. there are libs for unwrapping, there is a foss native lightmapper, ive looked at it occasionally trying to picture if its viable
it all seems viable, but i would not be able to maintain any of that unless i wrote it
It's certainly doable, just gotta weigh whether it's worth the effort
A fully featured lightmapper is a ton of work
Especially if you support hardware acceleration for it (which you should if you plan on doing this at runtime)
yeah its kinda, if you do it, youd go for retro shooters for good, several titles on that tech.
i dont think youd need that much effort put into optimization and acceleration, as low res lightmaps would suffice
We're planning on open sourcing the game we support BSP in (Dusk) under MIT so eventually more games can leverage that for modding
I kinda went a bit overboard lol, it supports a ton of variants of BSP
Source, Quake, Quake 2, Quake 3, GoldSrc, etc
Along with all the various variants per game
have you seen Prodeus level editor?
Yeah
not brushes, but still, its kinda the ideal variant, integrated editing
It's stored as brushes sort of
The map format is similar to Quake in that it's a text format set of brushes and stuff which later gets compiled into a bunch of meshes and other data
in prodeus?
oh i mean its not really csg
I don't mean the editor I mean the format it saves to
That I haven't
its a first time i saw something like that, they do csg with actual meshes as brushes. Directly build levels with meshes, with all the materials etc, all csg
how to do a foreach as an enum like so
enum Types {normal, medium, hard}
foreach(var item in Types){Debug.Log(item.ToString())}
>>>normal
>>>medium
>>>hard
Enum.GetValues(typeof(Types))
ty
I want to call the overriden CalculateAccuracy() method of class FlickNormalScoreSystem, parent class ScoreSystem in child class FlickNormalWeaponManager of parent class WeaponManager.
FlickNormalWeaponManager.cs
public class FlickNormalWeaponManager : WeaponManager {
private FlickNormalScoreSystem flickNormalScoreSystem;
private void Awake() {
flickNormalScoreSystem = scoreSystem.gameObject.GetComponent<FlickNormalScoreSystem>();
}
private void Start() {
flickNormalScoreSystem = scoreSystem.gameObject.GetComponent<FlickNormalScoreSystem>();
}
protected override void GunShotLogic() {
flickNormalScoreSystem.CalculateAccuracy();
}
}
FlickNormalScoreSystem.cs
public class FlickNormalScoreSystem : ScoreSystem {
public override void CalculateAccuracy() {
//logic code
}
}
- if i use the awake function it is straight giving error of null object reference.
- if i use the start function it gives same error on flickNormalScoreSystem.CalculateAccuracy() method call.
Parent class? Child class? Am I losing it, or are these not related at all?
its structured
#๐ปโcode-beginner try starting with a unity tutorial or programming tutorial, i like ray wenderlich's!
The GetComponents didn't find so they returned null
it's telling you what the error is: there's a null object reference
its not null i checked with null and debug log
it is just giving error on function call
Post the stack trace
how we dot that O_O
This just sounds like a race condition problem to me. Trying to load something else in another script before it had a chance to get it. Also, this should be in #๐ปโcode-beginner
Oh yeah you defo picked the wrong channel to ask in
i already ordered the script
Ordered?
script execution order
Oh
Post the stack trace. It's what's under the NullReferenceException error message, it points to where execution was when the error happened
its only monobehaviour class giving error if i use non monobehavior class without inheritance than there is no error
is there a pre-existing prometheus exporter / structured performance format for unity runtime?
talking about FlickNormaScoreSystem Class if i inherit the class from score system thant it gives null ref error else it works fine without monobehaviour
Sample stack trace
System.NullReferenceException: Object reference not set to an instance of an object.
at Program.Main()
Points to Main method in my Program class, for my case. You'll have more lines like these with more information, such as line numbers
NullReferenceException: Object reference not set to an instance of an object
FlickNormalWeaponManager.Awake () (at Assets/Scripts/Tasks/Flick Normal/FlickNormalWeaponManager.cs:11)
UnityEngine.GameObject:AddComponent()
GameManager:<SetupGameEnviornment>g__SetupFlickNormalTask|16_0() (at Assets/Scripts/Game Manager/GameManager.cs:88)
GameManager:SetupGameEnviornment() (at Assets/Scripts/Game Manager/GameManager.cs:76)
GameManager:Start() (at Assets/Scripts/Game Manager/GameManager.cs:46)
using Awake()
Okay, so it happens on FlickNormalWeaponManager.cs line 11
Post what's on that line
NullReferenceException: Object reference not set to an instance of an object
FlickNormalWeaponManager.GunShotLogic () (at Assets/Scripts/Tasks/Flick Normal/FlickNormalWeaponManager.cs:40)
FlickNormalWeaponManager.Update () (at Assets/Scripts/Tasks/Flick Normal/FlickNormalWeaponManager.cs:23)
using start()
flickNormalScoreSystem = scoreSystem.gameObject.GetComponent<FlickNormalScoreSystem>();
Okay so scoreSystem was null
its present in parent class working fine why null ? null during awake call ?
How is it retrieved, ie. where do you assign a value to scoreSystem?
Weapon manager Class parent of FlickNormalWeaponManage class
Yeah I got that, but where do you put a value into that variable
value ? you mean reference or logic for score system
I mean where are you doing scoreSystem = something something;
If you're ever doing it
I'm not asking where it's used I'm asking where it's assigned a value
No, it's called an assignment, when you do x = y, you assign x
And inheritance has nothing to do with whether the variables are assigned or not
It can still be in the parent class, unassigned
scoreSystem = GameObject.FindGameObjectWithTag("ScoreSystem").GetComponent<ScoreSystem>();
Parent class
yes
Is Awake overriden in the child class? If yes are there measures in place to run the parent's Awake, with virtual and override?
No that's good
So after that line ^^^ put Debug.Assert(scoreSystem != null);, play the game and watch out for "Assertion Failed" errors
if i use a non monobehavior class in FlickNormalWeaponManager, like FlickNormalScoreSystem flickNormalScoreSystem = new FlickNormalScoreSystem();
there are no errors
ok trying
Alright
scoreSystem = GameObject.FindGameObjectWithTag("ScoreSystem").GetComponent<ScoreSystem>();
Debug.Assert(scoreSystem != null);
like this
Yep
For good measures you would also want to check that this code is running at all, by doing a Debug.Log above those two lines
its giving error on scene load
NullReferenceException: Object reference not set to an instance of an object
FlickNormalWeaponManager.Awake () (at Assets/Scripts/Tasks/Flick Normal/FlickNormalWeaponManager.cs:11)
UnityEngine.GameObject:AddComponent()
GameManager:<SetupGameEnviornment>g__SetupFlickNormalTask|16_0() (at Assets/Scripts/Game Manager/GameManager.cs:88)
GameManager:SetupGameEnviornment() (at Assets/Scripts/Game Manager/GameManager.cs:76)
GameManager:Start() (at Assets/Scripts/Game Manager/GameManager.cs:46)
is score system not referenced or what ?
So the code on that line 11 is ran before the parent's Awake is executed
Or Awake isn't executed
child class awake ran first ?
You told me you didn't have Awake on the child class
First, make sure your code that finds the ScoreSystem runs
parent class WeaponManager have object of score system referenced in awake, child class FlickNormalWeaponManager have object of flickNormalScoreSystem refrencing in awke via score system
i posted code ๐ฆ
can't find why score system is null in parent
๐ฆ
So both of them have Awake methods, the problem is that if you have the child class attached to an object then the child class's Awake will run, not the parent's
Check that this is the case by logging something in both Awakes
ohh
logging which runs first
only the child will run unless you override a virtual method and call the virtual method from the overridden method
Yep exactly
bro child one runs first
๐ฆ
that's the prob
so should i make override function and call it in parent's awake
So make the parent Awake virtual, the child an override and in the child call the base implementation base.Awake();
bro that's all
thanks ๐
but is awake overriden available ?
As the base class' Awake is virtual yep
thanks bro, one thing i learned i need to revise the oops principles xD
f you
!warn 442885979104215042 Don't insult community members. You appropriate channels as directed.
STRENGTH#3425 has been warned.
*use , still asleep.
bro we chilling
if i have an object that could be an int, long, etc - number value type - how can i easily cast it to a double and also know it was a number type?
e.g.
if (value is asDouble double) {
}
will this be false for an int (because it's not a double) or true (desired, because I want to cast it to a double anyway)
essentially, is there a version of Convert.ToDouble(value) that does not throw exceptions
it just expands to if (blah is int X) if Blah is float Y...
can some one help me
ok
Is the as operator not what you want? https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#as-operator
it's unclear if it actually does the conversion
It does. It's as explicit cast
so value as double? - is it null when value is an int? @gray pulsar
do you see why this is tricky
it's not bad to write the switch statement
i was just wondering if it already exists
It shouldn't be null in this case, since the cast operation from int to double exists
is that how as works? the cast is defined for explicit casts
and it's not clear to me if as is an explicit cast
it's definitely not defined for a nullable type
Once you determine its type you would be able to cast it
It must be a manual process though.
The is, as, and typeof operators cannot be overloaded.
A user-defined type can't overload the () operator, but can define custom type conversions that can be performed by a cast expression. For more information, see User-defined conversion operators.```
public class Program
{
public static void Main()
{
object x = (int)3;
var y = x as double?;
Console.WriteLine(y.HasValue);
}
}
prints False @gray pulsar
You have to (double)x it I think
then i wouldn't know if the conversion failed or if the value was 0
https://dotnetfiddle.net/GMS67G correctly shows 3
Test your C# code online with .NET Fiddle code editor.
i'm trying to avoid throwing an exception
i suspect there must be a way to do this
in this example i can't tell the difference between a real NaN
I mean you should detect its type and cast it accordingly, I think?
but it's easy
yes, that's what i'm doing in this example
i'm wondering if there is already a C# shorthand for this, and it sounds like there is not.
actually
using System;
public class Program
{
public static void Main()
{
object x = (int)3;
var y = (double)x;
Console.WriteLine(y);
}
}
doesn't work ever.
There isn't yet. .NET7 (preview) has generic math and the INumber interface. Set to release next November, maybe in Unity in 10 years :)
I am proved wrong. Good to know
This could be disgusting but could you do something like this?
object x = // your number
if (double.TryParse(x.ToString(), out double num))
{
Debug.Log(num);
}
lol
@fresh salmon "I rest my case"
"Your honor, my client was just innocently trying to parse the string representation of the victim at the wrong place at the wrong time"
judge: "The Jury finds you extremely guilty"
Never do string parsing without specifying culture settings
You should be passing CultureInfo.InvariantCulture to ensure consistent results
Otherwise things will break very easily once the code runs on a system with a different locale
my switch statement works correctly
That's the cleanest way you can get for now imo
How in zenject inject CinemachineVirtualCamera follow variable with specific id?
does anyone have a good approach for breakpoints on exceptions in Rider?
ideally it only stops when code inside my Assets folder is in the call stack
but apparently "User code only" doesn't work at all
and not having that checked throws on all sorts of unity garbage
anyone know how to use TcpClient to host a local websocket a website can connect to?
ideally i'd like to connect to ws://localhost, but no examples i've found online work without a port
There's TcpListener which acts like a "server", though for websockets you'll have to handle the handshake and decrypting/encrypting protocol yourself
That page has the resources to set up a basic one https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server
And there's still the WS specs (https://datatracker.ietf.org/doc/html/rfc6455) if you want the raw thing
There are also assets available as NuGet packages that do it all for you, if you want to host the server outside of Unity as a console app or Windows service for example
so, i'm having the issue that var client = server.AcceptTcpClient(); never completes
i'm guessing there has to be some connection already open or something like that?
If the server is not running on the same computer check the firewall settings, otherwise check the URL+port number on both sides
no i mean, i'm doing this
using System.Net;
using System.Net.Sockets;
var server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);
server.Start();
var client = server.AcceptTcpClient();
Console.WriteLine("Connected.");
Connected. never prints
oh, nope, you're right
alright sick, thanks
so, i'm trying to send a simple string to the connecting website (it's a command that's supposed to execute some stuff). i know the command works, however, using the following code doesn't have any effect on the website;
using var writer = new StreamWriter(client.GetStream());
writer.Write("start");
what do i need to do instead?
using var stream = client.GetStream();
var bytes = Encoding.ASCII.GetBytes("start");
stream.Write(bytes, 0, bytes.Length);
this also doesn't appear to work
Hello, I installed the inthehand.bluetooth nuget package with NuGetForUnity But i'm getting this error when pressing play
NotImplementedException: This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation.
InTheHand.Net.Sockets.BluetoothClient.PlatformInitialize () (at <b58b6f76775240448daecb704cc009f5>:0)
InTheHand.Net.Sockets.BluetoothClient..ctor () (at <b58b6f76775240448daecb704cc009f5>:0)
There is a class with byte array field inside (2d or 3d does not matter). The values can change from outside the class Update(indices,newValue)
When setting some elements of the array to specific values, another method should be called as well to generate a new mesh based on the updated array.
Therefore, for some values, updating the array is enough but for specific values, in addition to updating the array, another method should be called to regenerate the mesh.
Defining a bool variable (dirty flag) and SetDirty is the right approach, right?
_chunkObject.Update(indices,newValue);
// call _chunkObject.GenerateMesh in the right place after all chunks are ready
// Chunk object class
public class ChunkObject{
public void Update(Vector3Int[] indices, byte newValue){
_chunk.Update(indices, newValue); // update the array
// set shouldUpdateMesh based on newValue
if(shouldUpdateMesh){
IsDirty = true;
UpdateMesh(); // only calculates triangles and vertices but not generate mesh
}
}
public void GenerateMesh(){
if(IsDirty){
// generate mesh based on vertices and triangles calculated already
IsDirty=false;
}
}
}
so, it would appear that my target website doesn't actually fully connect. it permanently stays on Connecting.... i'm fully sure that the issue does not lie with the website, though i can't quite figure out what's the issue...
marking some data set as dirty is a concept used by unity in many cases , i think it can work for your case
Is there a good way to make several atlas's(so say an albedo and a normal atlas) so that an object can have a single UV and be able to index into both atlas's if every object has 1 associated albedo texture, but only half of them have a normal texture?(I want to re-use the rects from the Albedo's PackTextures to place the normal textures on the normal atlas)
Hi everyone. I am making a custom build process for Android that needs to use .aab and Split Application Binary (OBB) and other preprocesses.
My problem is that when I use my custom script the UnityStreamingAssetsPack folder is created separately and not integrated inside UnityDataAssetPack. This difference causes Google Play to reject the .aab file.
Any suggestions on how Unity compresses everything inside UnityDataAssetPack? or which method is called.
Thank you very much in advance. I attach an image of the file structure of the exported project.
i have problems with my canvas scaler. it is set to scale with screensize, but if i change res (first pic) the images on the bottom left are getting displayed wrong. on original res (second pic) they are displayed right. could be an issue with my code, because the squares are getting instantiated
they have a parent, are getting instantiated like this:
curr = Instantiate(endRoom, parent: roomParent, position: new Vector3(room.x * 30 + xOffset, room.y * 30 + yOffset, 0), rotation: new Quaternion());
where xOffset is the space from the screen, room.x and room.y are just coordinates in a double nested list, 30 is the meant spacing between them.
^^ it seems to ignore that *30 ? i tried to set the positions manually, and when they align like they should (n * 30) it works, but they arent aligned that way, either the canvas scaler moves them or idk
instead of 30 (1366:768) it moves 63.6335 (16:9)
i think i got it
OF COURSE
you need to use anchored position oh my god
how stupid am i
Probably less than you think. ๐
That UI reminds me of a MUD mapping tool I used a few decades ago.. zMUD
nah i got this idea from dani (everyone knows dani) from this video: https://www.youtube.com/watch?v=YMWnwBpUgoI
Can I make another game in 2 days (48 hours)? Let's find out!
Download the game: https://danidev.itch.io/triangle-game
โคDiscord - https://discord.gg/dani
โคFacebook - https://www.facebook.com/DaniMilkman/
โคTwitter - https://twitter.com/DaniDevYT
โคSource code - Source code - https://github.com/DaniDevy/LudumDare45
โคMusic by Evan King. Tracklist be...
sounds like you should file a bug
https://hastepaste.com/view/BQ7IdUaCf6 Can someone help me understand why the .Isgroing is being set to true on the whole 2d array
I assume SeedSlot is a class, in which case every entry of your array is actually the same object (see line 94)
Hey, i want to make my own backend and currently i search for best-practices to get data in my online game.
Basically: i use Photon Networking and dont have access or did anything to the server so i just handle all the clients.
I would need to get Data from a MongoDB and would like to also use Redis (Pub/Sub mostly for live updates). Is it a good practice to make a connection on each client to these databases or is it way better idea to make my own RESTful Service which then calls the internal functions and give back the result?
I am not sure about connecting from the client to MongoDB for example, because i feel bad that someone can decompile the game (idk how) and get the password and do their own changes in the database
Never connect straight to your database from your user facing application
Okay thx, most people i found say there is no problem but i was not sure about it ๐
Then i do a wrapper service in between them ๐
Anything on the client side should be considered compromised
Any credentials your store there are compromised
If those credentials allow them to modify your database then that's terrible design
Yes. Set up a (or multiple) back-end that connects DBs and other APIs which it needs, and let the client send and recieve data to and from the back-end. That way you can also manipulate what needs to be sent. Say you fetch a huge list from a DB, but the client only needs a few entries, you do that on the back-end and only send the required data back to the client. Also remember to cache often used resources (like that huge list).
Also also, if there the client needs to have login credentials: remember to hash, encrypt, etc etc, before sending it to your back-end. And don't save it in plain text. Safety/Security is key!
๐
Any ideas why RigidBody2D.cast doesn't hit anything? The direction is correct, tried printing it, increased the distance, nothing works
both the player and the ground have box colliders
You need to use the 3d equivalent to hit box colliders
@fresh salmon I got my tcpclient to connect and do the handshake. I can connect successfully now. However, disconnecting via the target website (there's simply a Disconnect button, which calls WebSocket.close()) doesn't appear to work.
Disconnecting sends a (what I assume to be) encoded message, but decoding it results in a message length of 0 (bytes[1] is 128). Is there another way to find out whether I'm supposed to disconnect the client?
Perhaps additionally, is there a better way to handle receiving messages besides checking the _tcpClient.Available property in an infinite loop?
I think that trying to read the stream client-side when the server closed the connection results in an exception
Or, you could send a custom message that indicates "I'm about to end the connection!"
I tried using _tcpClient.Connected and _networkStream.CanRead, both of which remain true when I click disconnect
I'm not in control of the website, sadly
does the general advise of not using null coalescing and such with Unity.Object apply to this situation?
using UnityEngine;
public class BGMusicManager : MonoBehaviour
{
AudioClip bgMusicClip;
AudioSource bgMusicSource;
private void Awake()
{
bgMusicClip = GetComponent<AudioClip>() ?? throw new MissingReferenceException($"Missing {typeof(AudioClip).Name}");
bgMusicSource = GetComponent<AudioSource>() ?? throw new MissingComponentException($"Missing {typeof(AudioSource).Name}");
}
private void Start()
{
bgMusicSource.clip = bgMusicClip;
bgMusicSource.Play();
}
}
Correct me if I'm wrong, but I feel like the funkiness around whether it's truly null or destroyed-fake-null is irrelevant during Awake(), no?
I think that can safely be used here yeah. An alternative would be assertions:
Debug.Assert(bgMusicClip != null);
Which takes care of the semi-null shenanigans by using the overloaded operator
interesting. would you recommend that over what I'm doing?
It's less bulky and you have the possibility to pass a custom message as a second arg, so probably yes
typeof(AudioClip).Name?
Anyway. Maybe I haven't looked at TcpClient's properties enough yet, but I'm not sure how else I can check whether the target website is attempting to close the connection
As long as my app is running, the connection is open (website remains on Disconnecting... when clicking the button to disconnect). Only once I close my app (i dispose of the stream, then the client, then the listener) does the disconnection finally go through (obviously, since the connection is completely terminated)
Hm apparently yeah the Connected property is unreliable. That question covers it well https://stackoverflow.com/questions/1387459/how-to-check-if-tcpclient-connection-is-closed
This feels very expensive to do every loop iteration
I don't think that works because GetComponent also gives you a fake null when the component isn't there. At least I don't get an exception and log a "False" with this
private void Awake() {
Joint j = GetComponent<Joint>() ?? throw new System.Exception("test");
Debug.Log(ReferenceEquals(GetComponent<Joint>(), null));
}
on a gameobject with no Joint.
thank you!
Gives a fake null if it doesn't exist? What is wrong with them lol
can't wait for them to finish what they're working on so that they can maybe possibly in the future sometime if they feel like it move towards standard dotnet 6 and beyond
their system was written before fancy operators like the elvis operator ??= were added to csharp
Yeah, pretty sure they'll eventually do that sice .NET Framework isn't receiving updates anymore
i decided to experiment with sorcery. any idea why it doesn't throw the error? (the commented out code does throw the error)
@cedar ledge check this
public static class Ext
{
public static void EnsureComponent<T>(this Component owner, ref T reference) where T : Component
{
if (reference)
return;
owner.TryGetComponent(out reference);
if(!reference)
{
Debug.LogException(new MissingReferenceException($"Missing {typeof(T).Name}"), owner.gameObject);
}
}
}
then
void Awake(){
this.EnsureComponent(ref source);
this.EnsureComponent(ref rigidbody);
this.EnsureComponent(ref light);
}
i have something like that in another project, but it's more for any serialized reference rather than components. we already have the RequireComponent() attribute for ensuring components
i dont think your ref keyword does anything in your example, right?
ref on a reference only matters if you're assigning it to be a different reference
wait nevermind
i see how you're using out reference which is basically that
Ah your loop doesn't run because private fields aren't retrieved by default with Reflection. Instead specify that you want to get all of the fields:
.GetFields(BindingFlags.Instance | BindingFlags.Private | BindingFlags.Public)
Got fooled once because of that yeah
lol?
NonPublic*
Oh yep
will exception carry stack trace if not thrown?
Doesn't seem like it, new Exception().StackTrace returns null
i think the throw keyword does the magic
actually it would have to
because catching an exception and rethrowing it is common practice for APIs to hide their irrelevant inner workings
that process "recalculates" the stack trace from that catch block
yeah
makes sense guess you can wrap a call to trygetcomp into a method, throw there, try catch in the caller and log exception without rethrow
refering to what i wrote earlier
should i make my professor grade this code:
var fields = typeof(BGMusicManager).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(f => f.GetCustomAttribute<RequiredReferenceAttribute>() != null).Select(f => (f.Name, Value: f.GetValue(this)));
foreach(var field in fields) if(field.Value == null) throw new MissingReferenceException($"Missing reference to {field.Name}");
-reflection
-linq
-tuple
-misc terrible formatting
hold my beer
string assemblypath = UnityEditorInternal.InternalEditorUtility.GetEditorAssemblyPath();
var assembly = System.Reflection.Assembly.LoadFrom(assemblypath);
var type = assembly.GetType("UnityEditor.SceneHierarchyWindow");
var hierarchyfield = type.GetField("s_LastInteractedHierarchy", BindingFlags.NonPublic | BindingFlags.Static);
var hierarchy = hierarchyfield.GetValue(type);
var hierarchyType = hierarchy.GetType();
var sceneviewfield = hierarchyType.GetField("m_SceneHierarchy", BindingFlags.NonPublic | BindingFlags.Instance);
var sceneview = sceneviewfield.GetValue(hierarchy);
var sceneviewType = sceneview.GetType();
var treestatefield = sceneviewType.GetField("m_TreeViewState", BindingFlags.Instance | BindingFlags.NonPublic);
var treestate = treestatefield.GetValue(sceneview);
var expandedIdsField = treestate.GetType().GetField("m_ExpandedIDs", BindingFlags.Instance | BindingFlags.NonPublic);
expandedIdsField.SetValue(treestate, new List<int>());
beer at 7am? nice
honestly the only thing i hate about that is the m_ s_ prefix style
the hardcoded strings are a close second
That, and for me the vars
string assemblypath = UnityEditorInternal.InternalEditorUtility.GetEditorAssemblyPath();
var assembly = System.Reflection.Assembly.LoadFrom(assemblypath);
var type = assembly.GetType("UnityEditor.ProjectBrowser");
var projectbrowserfield = type.GetField("s_LastInteractedProjectBrowser");
var projectbrowser = projectbrowserfield.GetValue(type);
var treestatefield = type.GetField("m_AssetTreeState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
var treestate = treestatefield.GetValue(projectbrowser);
var expandedIdsField = treestate.GetType().GetProperty("expandedIDs", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
var assetsFolder = AssetDatabase.LoadAssetAtPath("Assets", typeof(UnityEngine.Object));
UnityEditorInternal.InternalEditorUtility.expandedProjectWindowItems = new int[1] { assetsFolder.GetInstanceID() };
expandedIdsField.SetValue(treestate, new List<int>() { assetsFolder.GetInstanceID() }, null);
type.InvokeMember("OnProjectChanged", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic, null, projectbrowser, null);
it's because it's copied from a method
this took a while to crack
Type implicitly if the type is clearly visible on the right side of the assignment, otherwise explicitly
Those don't happen to be the actual Unity internal fields right
they are
no, managed
what's it called where the type is inferred by the variable's name
in generics?
Implicit?
Hungarian notation? nValue
that's it
Oh, no
ah you mean self describing code or something like that
aah gotcha
f_health, s_name
vars are acceptable imo. i would prefer explicit types and no hungarian notation, but sometimes when you're game programming, you have things like AudioSource, AudioClip, AudioChannel, etc. where it's both difficult and pointless to name things not based on their type
Single_health, Boolean_isAlive
so if you're going to name things around their type anyway might as well var it up
Yeah, just don't do
var x = SomeObscureMethodThatDoesSomething();
i only do that when it's extremely inconsequential what the type of x is
ive seen some machine learning code f, d, di, dx, u, ih ...
its dominant when the main thing is algorithm
not only is IDE support utter garbage, but the variable name conventions do NOT help
guess its easily inferred from the context if you know what youre doing
if
well if you work with ml algos, guess its a must you know how math is denoted
no it's like Set Theory or Category Theory. It's a foundational system of logic kind of thing
but Type Theory is a lot friendlier to programmer brains from what i can tell
Haskell and other functional programming concepts basically stem straight from it
not me, never was interested
Me neither, but Lisp has representation like these especially for conditions if ((< x 2) ... )
I find it really weird lol
I don't think I changed anything significant here but now it's not throwing an error for any null fields
var fields = typeof(BGMusicManager)
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
.Where(f => f.GetCustomAttribute<RequiredReferenceAttribute>() != null)
.Select(f => (f.Name, f.GetValue(this)));
foreach(var (Name, Value) in fields)
if(Value == null) throw new MissingReferenceException($"Missing reference to {Name}");
And to top it off convert that to an extension method so you can do this.EnsureReferencesSet() in Awake
also - cache reflection results per type in a dictionary
linq to for loops
the field getter to delegate
yeah basically a map of lists of delegates
ive never done the caching thing, is it just storing the result of the reflection into a variable? just run that in OnValidate()?
why convert linq to for loops?
no you lazily cache it
if its not in a static dictionary - do reflection, create a list of getter delegates
put in a dict, retreive on repeating calls
because linq is slower and allocates
you do this inside the type itself, or in the static extension class?
some global cached data store static class
so the dictionary would be <Type, FieldInfo> or such?
no <Type, Func<object,object>> i think
Yeah lol made that error when I worked on some DB to type mapper, was painfully slow because I was calling Reflection for each row
Caching the stuff sped it up 10 times lmao
if you're only storing a dictionary of type and a func what are you caching?
yeah i have global TypeStore where i run reflection on all types once, and every relfection util that requires it can access cached version
that returns type IEnumerable<FieldInfo> not a Func<object, object>
only problem that i didnt solve with this approach yet is that ... relfection data is not garbage collected
so every type you ever retreive is there to stay
getters
you can convert field.GetValue into a delegate
Yeah but then you'll be able to loop through that and for each field info put its .GetValue method into the map
oh i see
i have some code for that nearby
Okay I thought that would be a new instance for each one is there a way to do that?
so you have a type and some field getters. last thing im confused about is how a 1D dictionary can store that. I feel like that would require Dictionary<Type, List<Func<>>>
its for a setter but the approach is the same for getter
var method = (Action<object, object>)dynSetter.CreateDelegate(typeof(Action<object, object>))
Delegate.CreateDelegate basically
yeah list
you can wrap the info into your class with a del, name, whatever else info you need, attribute
is there a way to simply do what ive already got, but put the awake code in the definition of the attribute?
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class RequiredReferenceAttribute : Attribute
{
private void Awake()
{
var fields = typeof(BGMusicManager)
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
.Where(f => f.GetCustomAttribute<RequiredReferenceAttribute>() != null)
.Select(f => (f.Name, f.GetValue(this) as UnityEngine.Object));
foreach(var (Name, Value) in fields)
if(Value == null)
throw new MissingReferenceException($"Missing reference to {Name}");
}
}
obviously that awake wont run
but you get my point
well kinda, but at the same time, its dirty
attributes are traditionally just storing data
so where do you typically make them do magic?
but i need awake, so i just stick that in a monolithic monobehavior that gets all fields from all types?
Sure you dont need a (static) constructor?
no in awake you just call a method
like that extension method from above
you can also run it in the editor on project change
omitting runtime completely
for even better results move it to a dll
it will then work even if the project fails to compile, so you wont miss anything because of it
now im thinking if project change detects any actual field changes, guess this route will have bunch of edge cases
Do you want this attribute to only work with the BGMusicManager type?
no
don't worry about it, it's just for fun
i need to focus on getting this assignment done due tomorrow anyway
i'll delve more into fun generics reflection stuff later
this does the trick for now:
public static class Validator
{
public static void Validate(this MonoBehaviour mb)
{
var fields = mb.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
.Where(f => f.GetCustomAttribute<RequiredReferenceAttribute>() != null)
.Select(f => (f.Name, f.GetValue(mb) as UnityEngine.Object));
foreach(var (Name, Value) in fields)
if(Value == null)
throw new MissingReferenceException($"Missing reference to {Name}");
}
}
public class RequiredReferenceAttribute : Attribute
{ }
private void Awake()
{
this.Validate();
}
๐
private void Awake()
{
this.Validate();
}
Maybe you can make some editor script that, after you enter play mode, scans all components for this?
an editor script that calls Validate() on each component in the scene?
what's the thing i need to search for to learn how to make a script that runs in edit mode AND runs without being in the scene?
or yano just cs public abstract class InsertName : MonoBehaviour { protected virtual void Awake() { this.Validate(); } } and then ```cs
public class Script : InsertName {
}
altho that feels weird
yeah but i dont want everything to inherit like that lol
it gets more and more wonky the more weird features like that you want
if you are mixing runtime here, you will get runtime overhead from the components that are interested themselves
if you are doing clean editor time, you will have to scan every prefab, every component in the project, which is slow, but its not runtime
https://docs.unity3d.com/ScriptReference/InitializeOnLoadAttribute.html
https://docs.unity3d.com/ScriptReference/EditorApplication-playModeStateChanged.html
The latter one has a complete example
Or, if it works for you, only search in the current scene. Maybe thats fine as well
detecting project change works in many cases, but im not sure how to deal with edits to components then
that caused some funkiness
the yellow bits are leftover playmode tint lol
they arent going away
k that worked perfectly
feel free to add performance improvements but im gonna leave it at that for now
Id personally not throw a missing ref exception. Its saying "Missing reference to abc, good luck finding it lol!"
I'd do a LogError, pass in the object that broke it in the context parameter. That way you know exactly what is missing, and where
fair enough. i guess once you move the error away from the class its a pretty good idea to use that debug.logerror functionality to direct the programmer to the right place
could probably use TypeCache instead of reflection there
im not familliar
public static void Validate(this MonoBehaviour mb)
{
var fields = TypeCache.GetFieldsWithAttribute(typeof(RequiredReferenceAttribute))
.Select(f => (f.Name, f.GetValue(mb) as UnityEngine.Object));
foreach(var (Name, Value) in fields)
if(Value == null) Debug.LogError($"Missing reference to {Name}", mb);
}
works the same, nice
nice
kinda cool that unity provides a way to get all fields from all cached types with the attribute just like that
yeah it's really useful in editor code
oh yeah TypeCache never used, that one bypasses the gc issue, but for editor only sadly
Wouldn't that also fail if you have a non UnityEngine.Object typed field with that attribute?
Which should be ignored rather than throw an error
is Unity.Object the only thing that is a drag and drop reference in the editor?
yeah afaik
Yes
so the attribute should have an error when put on something else
you can copy paste other things, like SerializeReference refs, or anything with Odin
i dont know if it works in base unity, try right clicking some property in editor
declaring type afaik
With something like that yeah
there it is
x.DeclaringType.IsAssignableTo(typeof(MonoBehaviour))?
if(declaring.IsSubclassOf(typeof(MonoBehaviour)))
i had .Where(f => f.DeclaringType == mb.GetType()) but it didnt filter it
this is not how you use it
var fields = TypeCache.GetFieldsWithAttribute(typeof(RequiredReferenceAttribute))
this probably returns you all fields in the whole assembly
what does it return btw?
yeah i only need the fields of the class im currently looping over
fieldinfocollection
weird
you should probably prefilter them by type, or do it somehow else
with current approach you are iterating all fields in the project and testing each, every time
IsAssignableFrom?
I don't remember which one to use here, but the logic said "can the declaring type be assigned to a variable of type MB?" in my head
yes its IsAssignableFrom
i didnt see To
so on the left should be the type you want to cast to, and on the right what you want to cast
should i just change it back to not using TypeCache? seems wasteful to loop over all fields of everything for each gameobject in the scene
is that the only api you can use in it?
never goes away
so it's not just me
its gonna be year 2077 and its still be there, my guess
.Where(f => f.FieldType.IsSubclassOf(typeof(UnityEngine.Object)))
i put it back to reflections and added that
it doesnt throw an error for my vector3 so it works
i think the only "pure" UnityEngine.Object is a "folder"
thats wack
youre probably safe
i got it
just had to swap the object to the left
k i've officially overengineered my class-final-project-in-24-hours game
doing a similar thing for AutoComponent
foreach(var f in fields)
{
f.SetValue(mb, mb.GetComponent<>());
}
what should I put in the <> ?
The type you want to get. But with generics, you need to know beforehand. You could use the non-generic variant if you dont
f.SetValue(mb, mb.GetComponent<f.FieldType>());
complains that f is a variable but being used like a type
wait
i didn't even know there was a non generic version
f.SetValue(mb, mb.GetComponent(f.FieldType)); works
Generics in C# have to be known by the compiler beforehand. Its not dynamic.
f.DeclaringType is a variable, the compiler cant know this beforehand.
yeah i just wanted to know how to work around it and that worked perfectly
I'm doing f.SetValue(mb, mb.GetComponent(f.FieldType)); and it successfully finds the component but then it still has an NRE when i use it in Start() of the script
i think that the start is running first let me investigate that
does start run before playModeStateChanged?
Start is called before, pretty sure
because im getting the debug log after the NRE from start
the debug log is called from playmodestatechange
NRE is from start
And you're doing all this just so you dont have to drag it in?
it's academic
Yeah clearly
๐
๐
๐
PostProcessSceneAttribute
Nah, those are DefaultAssets
i changed the intialize on load functionality to post process scene and everything works
if you ever wanted [AutoComponent] for automatically assigning your component references and [RequiredReference] for validating serialized fields when the scene plays (prevent forgetting to set them) here you go
i hope this isnt against the rules, i just dont want to flood the channel with even more of the same code
Awesome, thanks for sharing!
here's the usage just for quick reference
if i am currently drawing sprites in code in a horizontal line (in a for loop) for my player health (hearts / empty and full). I want to draw these along a bezier line. Is there a easy way to align sprites along a line in a UI? should I just forgo the drawing horizontally and just take a XY for each sprite? and manually draw them? Its for a UI and it goes along a curved background so I was thinking of either somehow drawing a line and aligning them all along the line? I do own ALINE 3rd party tool just in case that has any relevance, TLDR can i draw sprites along a curved line or should I make 10 points for 10 hearts and just manually asign them to the list of 10 points
in a UI canvas
Hey all, I've got a quick design question I've been going back and forth on in my head:
What is the best way to write maintainable C# MonoBehaviours?
It seems to me that we have the choice to either create larger, highly cohesive classes (Player) that become a massive burden to change and maintain due to size and complexity OR we create smaller classes (PlayerMovement, PlayerAttacking, PlayerInventory, PlayerHealth, etc) and split the functionality out making the classes easier to maintain but increasing the likelihood of bugs due to all the additional references that need to be wired up (either with requirecomponent or drag+drop in editor)
Any thoughts?
Unity mostly works with components, and imo that works well.
I do avoid RequireComponent for the runtime overhead.
If you destroy a component it will search if there is no RequireComponent on it.
How do you handle the complexity of wiring up references?
seems like we open up all sorts of avenues for bugs
Well arent you in luck ๐
How i do it is to have one central PlayerController, everyone links to that. And in turn, PlayerController also serializes a reference to the other components.
You could also only link from one to the other, making the dependencies very clear
Supposing we go with a components approach, how do you determine whether a thing is a component or a game object?
That guy above just made some RequireComponent, and AutoComponent.
We have something similar called GetComponent, which automatically grabs a reference when you open the inspector.
What do you mean? A GameObject is something completely different in Unity
"Projectile" for example
Is this a component or a game object? (prefab, for example)
Im sorry but the difference between a gameobject and a component is very big
A GameObject is a collection of components. Its a tag, a name, a bunch of components.
A projectile is a gameobject, with the components ProjectileMovement, ProjectileCollision, ParticleSystem.
Is "Head" not a "component" of a "Body"?
No, it is a GameObject within a body, with a Transform component.
so you do not compose a Head with a Neck and so on to form your body?
and your brain is a gameObject nested inside your head ๐
Yes, this is a transform hierarchy. Those are different gameobjects.
filled with all sorts of inactive unused deprecated components ๐ฆ
...if it is composed then it is a component of the whole
you see what I'm getting at?
how do you know whether something should be a MonoBehaviour (component) or a GameObject (component)
No, i think you're asking what the difference between a component and a gameobject is in code-advanced.
GameObject is not a (component). You cant inherit from GameObject.
You're giving me an answer in terms of code, I'm asking for an answer in terms of design
obviously I wouldn't need to ask in discord for the answer in terms of code, the documentation is available
if you goto a store and ask the guy to help you pick out windows and then realize you were calling a door a window, you realize that terms matter
A head is a GameObject, with a bunch of components. Since it has a position it has a Transform component.
is there a way to fix the fact that visual studio thinks that a private serialized field is never assigned to, and suggests it should be readonly?
i dont think that somehow adding the relevant suppressmessage attribute to everything with the serializefield attribute in an editor script is the "right way"
mostly i dont want to clog up my code with a million pragma warning disables, and i do find that suggestion helpful sometimes
this was my first idea (AddAttribute is not a thing)
public static class SerializedSuppresor
{
public static void Suppress(this MonoBehaviour mb)
{
var fields = mb.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
.Where(f => f.GetCustomAttribute<SerializeField>() != null);
foreach(var field in fields)
field.AddAttribute(new System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("IDE0044", "IDE0044"));
}
[InitializeOnLoadMethod]
private static void SuppressEverything()
{
foreach(var mb in UnityEngine.Object.FindObjectsOfType<MonoBehaviour>())
mb.Suppress();
}
}
Configure your ide to ignore the warnings?
how do i configure it to only ignore it when the field has the serializefield attribute?
I dont think thats possible out of the box
darn
There are already analyzers that achieve this
They should be built-in if you install the Unity tools for VS
There is also https://github.com/microsoft/Microsoft.Unity.Analyzers
is the best way to install this using the way you were showing me a while ago, or do i just do it from vs2022
The easiest way would be to just install the VS extension yeah
You could embed the analyzers in the project but it's significantly more work
it says that the analyzer should be included already
i did the vs code installation anyway and no dice
I'm trying to use Rigidbody.AddExplosionForce(...) for rocket launchers in my game, and each player is a capsule collider. One problem that I've noticed, however, is that if the explosion is on the player but below its center, the player, they aren't launched into the air, but just pushed backwards.
Which makes sense if you think about it
But that's not the style that I'm going for
Is there a way to add explosion force based on the center of the player?
https://docs.unity3d.com/ScriptReference/Rigidbody-centerOfMass.html
will this work for you?
for each hit, apply the force in the direction of (centerOfMass - explosionOrigin)
aert
Hello, I have a script Player that has an array of Tile gameObjects in specific positions.
As seen here, the blue board is the player and the gameObjects are those visible tiles.
I want to create a backup of those tiles which would basically be a duplicate array of the player's hand, by using deep cloning.
I wanted to ask if that's the appropriate action to take for an option to "Undo" the player's move if I can do something else.
If you go the cloning route, I would recommend making the duplicate backup arrays be not of type Tile. If you expect to generate a lot of these duplicates. I would investigate creating some kind of ID system so your arrays can be of a different type
I'm not sure I follow, what kind of an ID system?
I wanted at first to create an array of references themselves to the gameObjects so I can use them later on but I can't seem to think of a proper idea.
There are some chunks and each contains voxels.
Is it standard to use IJob for each chunk and inside, utilize IJobParallelFor to calculate some math/calculation for each voxel?
Then after all chunks are ready (JobHandle.CompleteAll), render meshes.
specialAttackCoolDownTimer -= Time.deltaTime; seems to be taking double the amount of time I think it should. I'm setting it to 6f but its taking 12 seconds to get to 0 in my update function
what is Time.timeScale set to?
it's set to default, but it's ok I figured it out after some more digging.
@plucky laurel so if I programmatically copy a static class/ file into my project I want to immediately execute one of the functions
There has to be some sorry Of attribute in unity that allows me to do this
I found [unityEditor.callback.didReloadScrip]
But that only trigger on second import
ok so. I need to make an A* Algorithm. But my node graph is a bit nonstandard, so I can't conceptualize it in my head.
My nodes have a position that they are in, and also a world, which is a completely separate space, and nodes can connect between worlds (like portals). However, the worlds' physical space do not line up; a node at (2,2) in world "Overworld" may connect to (0,0) in world "Dungeon". so how on earth do I do Heuristics for A*?
or do I need to do a separate pathfinding algorithm entirelty
Are you wanting an entity to be able to path through multiple worlds?
In that case I'd take a theoretical view at how A* works. As you probably know, all it does is assign each spot on a grid a value depending on the destination (and other modifiers a dev might put in IE maybe a tile is a "quicksand" tile or something that might increase it's movement cost in A star), and then uses those values to find the fastest path to the destination.
While this is great for a single map, it gets far more complicated when stitching bits and pieces together (although it's of course doable).
Perhaps in this instance, you could simply use standard A star to path to the appropriate "portal" node and then repath after it enters a new "world"
though you might want to keep a pool of data for each world that includes where each portal leads etc. So you could theoretically have an entity path from World A to world Y by stringing together various paths to portals based on qualifying factors
Yeah Iโm slowly coming to the conclusion that Iโm going to have to do separate path finding for each world
Well. Since each world is a physical space, whenever the algorithm enters a portal it could adjust the coordinates of the new world to match like putting a pin through paper
This does not need to have unit accuracy
I'd love it if someone could perhaps help me with Animation Events? I'm trying to figure out how to use the Object reference parameter with some custom object types (in my case, hitbox parameters, for instance). How do I use AnimationEvent objects, the docs are about as clear as muddy water lol
Some code for ref.
you may be able to reference a ScriptableObject that holds the data you need.
have you looked at ultimate fighting toolkit?
is this your code?
is this rummikub?
in my experience it is easy to write maintainable monobehaviors for things that already look like CRUD applications - an inventory system, menus, dialogue trees, etc.. Everything else follows really specific traditions that you should follow. like don't make a "maintainable" "FPS" "controller," find a historic implementation and reuse it
Yes, this is my code. I've implemented a "custom scripting" system using Scriptable Objects, and I want to translate them to Animation events created via code (clip.AddEvent(x). I'm using the AE's for timing purposes, as I can't seem to recreate perfect frame timing with my custom system alone.
I posted this in code-beginner, I don't think this question belongs in there.
Using a compute shader, I call GetData() immediately after Dispatch(), is this good design? Or should I be calling Dispatch() as soon as possible and GetData() as late as possible similar to Unity's Job system?
Yes!
So I'm making a spell that needs to make ice spikes in a radius around a target position. I'm using a Vogel spiral to pack them. GetSpiralPositions returns a list of positions corresponding to the positions in a spiral. I'm trying to "normalize" these positions, so that they all fit within a given radius by simply finding the magnitude of these positions, and then multiplying them all by a constant value calculated by the ratio of the radius to the maximum of these magnitudes.
Method:
public List<Vector2> GetSpiralPositions(int positions, float radius) {
float theta = 0;
float maxLength = 0;
var returnValue = new List<Vector2>();
// Algorithm adapted from http://www.smokycogs.com/blog/drawing-spirals-in-c-sharp/
while (theta <= positions * 360) {
theta += 137.5f;
var currentRadius = Mathf.Sqrt(theta);
var currentPosition = new Vector2(Mathf.Cos(theta / 180 * Mathf.PI), Mathf.Sin(theta / 180 * Mathf.PI)) * currentRadius;
float length = currentPosition.magnitude;
if (length > maxLength) {
maxLength = length;
}
returnValue.Add(currentPosition);
}
Debug.LogFormat("MaxLength: {0}", maxLength);
// Go through each return value and "renormalize" the values, so they fit in the radius.
float normalizedMaxLength = 0;
for (int i = 0; i < returnValue.Count; i++) {
returnValue[i] *= radius / maxLength;
float length = returnValue[i].magnitude;
if (length > normalizedMaxLength) {
normalizedMaxLength = length;
}
}
Debug.LogFormat("NormalizedMaxLength: {0}", normalizedMaxLength);
return returnValue;
}
Full script: https://www.toptal.com/developers/hastebin/ulasegupuy.csharp
I am testing this by spawning a sphere with the same radius at the same position. I expect that all of the positions given by GetSpiralPositions to be inside of this larger sphere, but I'm getting them outside of it. Not sure why, any ideas? I'm calculating the max renormalized length and logging it, it's 5
Here's a pic of what I'm seeing, small spheres are in positions yielded by GetSpiralPositions
Pattern is correct though, just something weird with my "renormalization"
Also, I'm aware I have a currentRadius already and don't need to calculate length again, just wanted to be double sure. Trying to just use it yields the same result
to reduce compile time each time I save one script in a big project I have to create .asmdef file or something to make unity compile only scripts in the folder where the script changes?
Infallible Code did a video on them too, but they're still black magic to me
I'm struggling with the options
what it means?
Which are the "predefined Assemblies"? It's the default "AssemblyCSharp" or what else?
Is there a way to make a list into a property that checks if the element we are trying to get even exists or is within the array length?
The list is with a custom class also, if that matters cs private List<SlideDigit> digitsList = new(6);
so im working on voxel game and i have no idea what to do now because this is nuts my max object size i was planing in bytes is large
(16ย 777ย 216 voxels) * (8 bytes) with gives me 128 MB per object
with is not good for streaming it in anyway (network,gpu,hard drive) and files will be large yes i can split it but problem stays the same
so i was thinking about using a bits instead of bytes
min bits i can store is 8 per byte
so lets say
"[0]0000000"
fist bit is a voxel state 0 full 1 empty with leave me with 7 bits to use
so i need to fit color data
with dynamic color is out i need to use palette any idea how to encode it
final size for object i can get is 16 mb
tupple can be useful for such situation
public (bool exist, SomeObj item) GetSetItem(objParam item)
{
(bool exist, SomeObj item) ditem = (false, null);
ditem.item = someList.Find(x => x == item);
if(ditem.item != null)
ditem.exist = true;
return ditem;
}
that looks overcomplicated
do you think? ๐
what im doing is split the datetime time into separate digits and for each element of that class and do cs digitsList[0].SlideVertical(targetDigit, transitionTime);
i know of another way that involves formatting it into a string and just doing a for loop, but it feels like that one would have too much GC
Yes. If Auto Referenced is enabled, then your assembly definition is automatically referenced by Assembly-CSharp and Assembly-CSharp-Editor
{
if (!photonView.isMine)
return;
PhotonView target = collision.gameObject.GetComponent<PhotonView>();
if(target != null && (!target.isMine || target.isSceneView))
{
if(target.tag == "Player")
{
target.RPC("ReduceHealth", PhotonTargets.AllBuffered, BulletDamage);
Instantiate(bloodSplat, transform.position, Quaternion.identity);
}
this.GetComponent<PhotonView>().RPC("DestroyObject", PhotonTargets.AllBuffered);
}
} ```
Hello, i am trying to instantiate the bloodsplat particles when the player gets hit, however it only appears on the client side, it doesnt show up on the other clients side.
how can i make it so it appears on both sides
PhotonNetwork has a Instantiate implementation that will spawn object over the nerwork
Otherwise you got to call a rpc or raise your own netwotk event
I've been working on an inventory system and I made my items scriptable objects. I then made a item database that has a list of items that I populated with my item assets. Then, when I want a certain item I'm doing an instantiate inside the item database on one of these items to get a copy.
I don't know if this is a good way to do it. Does it sound OK?
Sounds fine
Whats the problem for it assigning the previous duplicate element instead of the next one?
private void OnValidate()
{
SlideDigit[] allSlideDigit;
allSlideDigit = GetComponentsInChildren<SlideDigit>();
for (int i = 0; i < allSlideDigit.Length; i++)
{
if (!digitsList.Contains(allSlideDigit[i]))//if we dont have a class in the list
{
for (int j = 0; j < digitsList.Count; j++)
{
if (digitsList[j] == null)//assing it to the free element
{
digitsList[j] = allSlideDigit[i];
break;
}
}
}
}
}
You really need to stop nesting like that and start using foreach
I don't really understand your question or what you are trying to do
its just 2 for's- and im trying to automatically assign any missing components if theres a free slot
It's two for and two if statements that seem to be rather redundant and uneeded
foreach is also slower, plus its doing literally the sam ething in the end; i just went the for route
how is it unneeded?
it goes through the GetComponentsInChildren list, if one of the components it goes through isnt in the actual class's list, go through the class's list and if it finds an empty (null) element, assign it there
The only thing you care about is if digitList[index] is null, so a huge chunk of your time spent in the for and if statements looping through elements is wasting time.
๐ค
You say it's faster, I say it's backwards. As 95% of the time it'll ignore the element at the last if null statement
Anyway you seem intent to do it the way you are so I won't nitpick and let you work through it how your comfortable
i was just wondering why its not assigning the right element if its just one added element instead of the whole list
(like in the video)
private void OnValidate()
{
// only gather null list item entries
foreach (var listItem in digitsList.Where(x=>x==null) {
// find missing children
var firstMissingItem = allSlideDigit.FirstOrDefault(x=>!digitsList.Contains(x));
// assign it if we found one
if (firstMissingItem!=null)
listItem = firstMissingItem;
}
}
That's how I would tackle that. I havent tested the code, and you can separate it from LinQ if you want.
Or if you want simplier, non-linQ
private void OnValidate()
{
var allSlideDigit = GetComponentsInChildren<SlideDigit>();
for (int j = 0; j < digitsList.Count; j++)
{
if (digitsList[j] == null && j < allSlideDigit.Count)
digitsList[j] = allSlideDigit[j];
}
}
@wooden cedar these dont work as my code though; its assigning it differently
theres a reason why i have two for loops
theres an array, and a list
they are different
I know
the list can have less elements than the array
I know
You are going through a list, looking for empties, and assigning the first item missing from an array of children
yup
wait no
looking through an array, checking if the element in the array is in the list , and if its not , assign it
Well what you are actually doing is going through a list of children, checking if they are missing from the list, then checking if the list has any empties, and then assigning it to the list.
Which is backwards. Because if the list, which changes rarely, has no empties - the rest doesnt matter.
Hense, why I inverted it
gotcha
As it is, you are marching through all the children regardless of if the list even has an empty
well your non-linq code has the same problem
unless i go from 0 elements to the chosen amount, it will just keep duplicating the last one
I cant, eye ball wise, see why your original code was doing that either, i kind of hoped it was just a j vs i for loop issue. Sorry my friend
weird
This function is supposed to save my neural network and then later read the values from it and use them, idk why but it does not work https://gdl.space/ekayomivar.cs pls help
U dont need to understand neural networks
Can you elaborate on "doesn't work"?
Are you getting errors?
Is the wrong thing writing to the file?
Is the wrong thing reading from the file?
Provide some details
hey, I have a snippet that works until my character is rotated:
Ray ray = Camera.main.ScreenPointToRay( Input.mousePosition );
if( plane.Raycast( ray, out float distance ) )
{
Vector3 worldPoint = ray.GetPoint( distance );
direction = ( (worldPoint - GunTip.position) ).normalized;
Direction = direction;
}```
my character travels on Z
Im trying to shoot towards my mouse
umm sorry for the wait I dont get any errors however I do get weird behavor that should not happen(behaves very differently than what I saved)
sick. i think the best thing to do is, the UI "stages" the player's move, and then once they end their turn, it's committed. that seems clunkier though - how often will people undo?
yeah it's very very tricky. i mention the other asset because it aspires to do the frame timing and maybe it's worth buying to study it. i own it but haven't researched it yet
It changes the tiles on the board, and then when clicking the Finish Turn button it checks the board's validity, if not valid then it returns all the tiles back to the player's hand.
In case you wonder how it looks here:
"traditions" seems like an extreme anti-pattern.. no way to utilize knowledge of software engineering, just gotta memorize the gotchas
Guys, would u rather use PlayerPrefs or create a custom static class that stores your data? And why?
PlayerPrefs = simple preferences. Stuff like volume, player nickname, shadow quality etc. For actual save data you use a custom saving system
Ok thankyou!
Neither
Make a properly structured data class and serialize it
Thank you very much
neither, ScriptableObjects
hello so i have a problem with my game at the moment
so when i create a room it creates it but it doesnt show a join room button
it was working but then i added some unity assets and it doesnt work anymore
Indeed. This is a fangame so I'd rather not have to invest in money assets, etc. I just can't seem to recreate this perfect timing events have. The game's framerate always gets in the way with its spontaneous changes.
yeah Unity sucks for fighting games
timing is extremely tricky
and if you want to implement rollback netcode you gotta reimplement half of unity stuff due to lack of determinism
It's a shame, because Unity is so damn easy to use (for the most part). So really for this I have NO choice but to use the events. I didn't want to, but custom timing stuff is virtually impossible to implement.
yup yup
Best bet would to get UFE
it's a bit of a pita to use but at least it works
You've given us almost no specific information here, really impossible to help. Also possibly sounds like a #๐ปโcode-beginner question.
i don't know if this is the most appropriate place to post this but i can't find anything on google and it's making me go crazy, every time i scroll the inspector it has those trail things, at first i thought it was my monitor, but then i confirmed it happens on my other monitors too, secondly i tried to record it and sure enough that's what is being processed, if anyone has any solution please help me, i feel like jumping the boat and freaking out about my graphics card won't help, but i did notice something similar happening in KSP
it started today, i didn't update drivers or anything
What graphics card do you have? Have you updated drivers for it recently?
i have an RTX 3070, and no didn't update any drivers
I would try that then
praying for that card
yeah it served me well, got it for cheap at the height of the chip shortage too
i will see if there are any updates
i also noticed that they only disappear when i move the mouse
could it be a unity screen refresh issue?
yeah updating the drivers didn't help
ok
thank God
i reset all my nvidia control panel settings and it seems to have fixed it
sorry for bothering you guys, i was just really worried about my gpu
I'd rather not, if possible, but animation events should still do the trick. We'll see, I have an idea on how to implement my system via the events.
If you arent blending
then animation events would work
if you are blending then they wont, blended animations still send events
you would run into weird cases where cancelling some animation states would still send events
the value of an FPS is people's familiarity with it. modern warfare and fortnite, the last two FPSes with a large portion of the audience new to the genre, are based on decade + old engines. best not to innovate in the least interesting part of an FPS, the controls and weapon behaviors. behold, with the exception of maybe Portal long ago, there hasn't been a new idea in a weapon / FPS movement since
Apologies, I thought you were referring to traditions of MonoBehaviour design not game mechanic design
sort of. if i were authoring an FPS, i would copy the code of a pre-existing FPS exactly, to start
unity is bad for FPSes, but i hear good things about Opsive's asset
if you were going to make an FPS, use unreal
like what is there to maintain? better to not maintain that stuff at all
I was referring to a more abstract concept than something that could be tied directly to a single genre
there are gotchas in the biggest genres that should be memorized
lots of people try to make Metroidvanias with Unity for example
corgi 2.5d engine doesn't recreate it faithfully, but it's close enough
let moremountains maintain that stuff
Ahh I think Iโve encountered what youโre talking about. Iโd call those โpatternsโ or โimplementationsโ
otherwise, it's a giant single class
because that's what metroidvania codebases looked like
and they did things that are only possible with god classes
Right.. kinda makes the whole โgame devโ concept less creative and more ritualistic
i agree. making a metroidvania is a ritual
and yet look at the success of Shovel Knight
At what price, though? Learning very specific details of very specific OOP or Unity quirks
Step into a new language or platform and I might as well be a junior again ๐
the ceremony of cloning the basics of a game at least puts a working build in front of you
Also semi-time-gated upward mobility in the industry
(Great conversation btw, thanks for indulging me)
Link?
My bad
question, does anybody know of a method to get mouse position even when the app is running in the background? (while tabbed out)
Most operating systems won't allow this for security reasons
found a solution
This function is supposed to save my neural network and then later read the values from it and use them, idk why but it does not work https://gdl.space/ekayomivar.cs pls help. I dont get any errors however I do get weird behavor that should not happen(behaves very differently than what I saved)
Pls tag me
@orchid hinge you should probably not be saving your floats as strings and parsing them
Why not?
What's wrong about that?
someone correct me if I'm wrong but I don't know if serializing floats that way is lossless
So like I lose some of the information?
potentially yeah
Like from 0.287637 it saves 0.28764
or something like that
Oh
better to save the actual bytes of the float
That seems kinda complicated ngl
Do u have a tutorial that u know that works?
you're making a neural network
Ye
@orchid hinge google ftw https://stackoverflow.com/questions/4635769/how-do-i-convert-an-array-of-floats-to-a-byte-and-back
U just do prev neuron * weight (with each neuron) then u add a bias and sigmoid it
cool beans
The code doesnt even compile
which code
the answer
You'll need system.buffers
alr
hmm that did not help lol
In that one minute, you found the system.buffers dll, downloaded it, and copied it into Unity?
?
which answer
Ill just use an yt tutorial
@granite viper Technically I could multiply my floats by 1000 when saving and then when reading divide them by 1000
sure, that might help
it's really not that difficult to just write the bytes tho
you can convert the 32 bit number into hex and then it'd be an exact (string) representation
I save them as txt so I could instead of saving them immediatelly just pass them through a formater and then save them
perfect this worked wonderfully
tysm for ur help
Its like a dumbass sollution but that kinda suits me lol
ye tysm again
do you have any ideas how to rotate overlapbox depends on player x movement
smth like this
{
var move = movement.Move;
if(move == Vector3.zero) return null;
return Physics.OverlapBox(transform.position + boxPos, boxSize, Quaternion.LookRotation(move.normalized, Vector3.up), interactableLayer);
}```
I've tried this but its not working quite well, it works but like its happening with delay
edit: not advanced question, keep it in code-beginner
@chrome vault Don't crosspost
show code, pseudo code, or anything that helps understand what you mean
Dw they crossposted
And there is if statement that checks if object reached target
It this works then I need new float for z axis
this is not an advanced question
New float is random number
@plucky laurel
Hey, I'm not sure my question is advanced, but I'm seeking for knowledge about implementing AI that can fly through circles.
At the most basic version of it it's clear, but what if an agent is behind the circle and should get back to the track?
I don't know if it is advanced but I needed to use RestSharp in my project due to API problems and the function that executes the request freezes the main thread even with coroutines. What would you suggest for this situation? Should I use another thread as the value is not required immediately?
How I get this string in another script file?
Thats not coding advanced. Thats code-beginner
you can use UniTask to run restsharp's async methods on a worker thread while setting data on the unity thread within one Task
that said you probably do not need to use restsharp. are you trying to use an openapi generated client?
yes
so it's not really an api problem
use unitask and the async version of the generated client
my problem wasn't the restsharp but the how I handled the response. Basically. I wrote wav file into disk with File.WriteAllBytes and it obviously creates a thread and makes the whole Unity wait.
the blocking call is going to do just that... block
you can use the async write calls
not my brightest day tbh
you shouldn't be creating threads
use unitask / async await to do this stuff expressively
Thank you. I will correct it.
you're doing great
you're using openapi... you're already miles above everyone else here
uh no?
having the same script doesnt mean they have the same exact state
it's as simple as having a boolean to check if it was fired or not
Which of the two should be destroyed?
For you, but not for everyone.
"i want the one that was fired to destroy"
You'll need to be able to differentiate this. What does it mean to be already on the floor?
Is it the one with the lowest Y, or the one with a bool isOnTheFloor?
you have some kind of other script thats firing this prefab
Please try to include as much information as possible
It's because it takes the data from database, it's a multiplayer game, and I wanted to know how I get the token of the user who is logged in...
I am afraid you will need to be more specific about your issue
is the prefab already a poison pool when its travelling? does it become one in contact? how does that work
you need to be more specific, we dont read minds
then again, just have a bool to differentiate them
your boss spawns those prefabs
you can use the boolean or a string or whatever variable you want to store its current state
the way I see it, if your prefab is travelling it has one state, and if its not it has another
your boss should set that on instantiation
and the projectile should change that when becoming stationary
well, now you know what to do ๐
let me think it through a bit
im just tired
of sitting coding 11h straight
xD
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.name == "PoisonPool")
{
//destroy other
}
this should work right?
even if's the same "object" its not the same instance
that will destroy both most likely lol
or one of them, randomly
again, you need a way to differentiate them
im not
its destroying other
if (other.gameObject.name == "PoisonPool")
{
Destroy(other.gameObject);
}
good for you, next time ask away in #archived-code-general and provide more details ๐
but i can see why we both think it should destroy both tho
im a bit confused
what's going on xD
so i have a monitor model
how can i make an "OS" in it
and be able to display it
Don't cross-post, stay in code-general
How I set texture from path when player click on button?
I tried this, but don't work:
Material FloorPaint = Resources.Load("/Prefabs/GameData/Paints/Floor/Wood/Texture", typeof(Material)) as Material;
Using Resources.Load requires your item to be in a valid resource folder. Means you need to have a folder named "Resources" that path is in. For you, anywhere under your Assets, it'll search for a Resources/Prefabs/GameData/Paints/Floor/Wood/ folder
The docs do tell you
And I should hope that at this level, we are reviewing the docs
Gimme a minute, i did this last year
you can load pngs as valid textures from any folder in windows
lol
What?
We're loading a Unity Texture not a PNG
