#archived-code-general
1 messages · Page 201 of 1
Oh so rather than Vector3.foward, I use transform.forward?
transform.forward tells you which direction is "forward" for that transform
Yep that did it! Thanks
and transform.InverseTransformDirection(transform.forward) is equivalent to Vector3.forward (:
Apparently some people use [serializefield, HideInInspector] private component, then use GetComponent in OnValidate
i don’t understand. what’s the problem with that
I've never liked doing stuff in OnValidate
I know I've had issues with objects not actually existing during it
(that's very vague)
what if your reference is on another object?
is anyone here familiar with this package?
https://github.com/vertxxyz/Vertx.SerializeReferenceDropdown
I have installed it, but still have no definition for [RefrenceDropDown]
well, you wouldn't use it if the component wasn't in a known location :p
this is mostly for GetComponent calls in Awake
It lets you automatically set stuff up before the game runs
although it also means that your'e doing a lot of work every time OnValidate gets called for any reason
which is everytime you save/change something in inspector iirc
I currently call GetComponent on every collision callback
just seems like an over-convoluted thing to solve something that isn't broken
maybe I’ll make a big dictionary to speed that method up
probably the mod who made it xD
That's fine. It's unlikely that it's taking long enough that you'll see a difference with a dictionary cache.
checks out 
yeah. I’ll think about optimizing some other time.
did you use UPM to install it?
are you using assembly def
I installed following the steps on git
You could use layers (possibly tags?) to return early so you arent calling it on unnecessary objects. Still tho this should be fine
and is it inside your Package Manager showing as installed?
it’s fine, and every so often people say it’s really slow, but i don’t think that’s the issue
do you have compile errors
🤷 only thing I can think of is you have maybe assembly def files or compile errors
sorry Im still a little new to all this, assembly defs?
assembly definitions group your code into DLLs. Code in assembly A can only reference code in assembly B if A references B (and you can't have cycles)
You often give library code an asmdef, since it can't possibly know about the rest of your code anyway
assemblies speed up compilation
If you have never created an asmdef of your own, then your code is in the default assembly, which automatically references every other assembly
so it wouldn't be an issue
gotcha, so in this case will I or will I not have to create an assembly definition?
you dont create one
Do I add the collision detection in the character controller?
since you're new this doubt you created one so it shouldn't apply to your case
If you haven't created one for your code, then it's not relevant
what kind of collisions we talking?
are you talking about the OnControllerColliderHit message?
Yes
That gets sent to every component on the same object as the character controller
Any of them can receive it.
It makes sense to put it in the same component that's responsible for moving the controller
its just a callback for collision, it doesn't actually make it collide or anything
Just a collision that allows the player cube to push the others
I sent you the code
did you try it
well it seems to work now... Must have needed to recompile and didnt do it automatically
idk
Thank yall for the help
Yes but it keeps saying it isnt compiling correctly
what is the error?
there should be none since its code from Unity example lol
All assemblies except those that have Auto Referenced set to false.
oh right, I had it the wrong way around
it's about things have Auto Referenced enabled on them
Oh i forgot a ; on the float variable
you should probably do this mane
!vscode
assuming your code editor isn't working, yes
is it showing this red unerline inside code editor or unity console error?
So it compiled now lol, but nothing is being pushed
how much push power you added
2.0f
play around with different values see if it helps
are u sure those boxes are Rigidbody and not static/Kinematic
No 100 doesnt move it either
Nevermind it had kinematic
It does move after all thanks!
make sure you configure your code editor if its not underlining spelling mistakes especially
Yeah thats what Im working on next
you dont want to be swimming with sharks without cage, sure you can do it but not a very good idea 😛
yeah, you really want VisualStudio to guide you to the exact variable names, or you will go insane
GPT's version of analogy
Having a configured IDE for coding in C# is like having a well-equipped kitchen when cooking a complex meal
lol
It significantly reduces the amount of typing you have to do.
so you spend less time converting ideas into code
so you have more time to bikeshed pointless things, like I am right now
(I'm overdesigning something that I have no use-case for yet)

Interesting, almost what GPT said on that point:
Focus on Creativity: With a configured IDE, you can focus on the creative aspects of coding and problem-solving, much like a well-configured kitchen allows you to focus on creating delicious dishes.
"significantly reduces the amount of typing you have to do." https://github.com/features/copilot 
an important characteristic of code completion is that it reduces the amount of typing you have to do without generating patent nonsense
It just makes programming less obnoxious
90% of the time it spews nonsense
intellicode for vscode has entered the chat
i had to turn that off immediately
it kept suggesting nonsense names and generating lines of code that made zero sense
actively getting in the way of writing anything
i don't get how they can make it work so well on windows but so shite on vscode
i thought they used the same intellicode
on visual studio, you mean?
Yup, the non consensual auto fill is crazy too
"intellicode" is not "intellisense"
yea
intellicode is some kind of AI vomit
whichever likes to autocompletes or w/e
in lieu of actual static analysis
boing
maybe we should add a footnote to the VSCode instructions about how to turn that off
int x =
did you mean:
int x = GetComponent<RigidBody2D>().position.x?
genuinely frustrating to do any work with it on
If they want us to switch to VSCode for mac they better make this shit work soon
intellicode works well on VS tho why can't they make that good
this is why we don’t let ChatGPT code for us
Intellicode is AI but iirc learns from your own code
so it offers actual useful stuff saving typing 2X
"oh you were gonna write a loop with this, here you go"
..writes whole loop
ok maybe a loop is bad example because you can tab for twice
but you get what I mean
its good /useful when it works
i’m just happy that I can block visual studio from automatically putting { on their own lines
so many unnecessary blank lines makes it hard to read
Ohh like code formatting?
which style
that is what I do
its very popular on java and javascript i noticed
it is vastly superior to making a whole line for {
I can an array of a type which can return an array. How would I easily get an array which contains all elements of all the arrays I get when I call the method on each element of the array?
after a while I dont even notice the { on the new line tbh
it starts to look like python to me xD
you may want a struct
or an array of areays
I was thinking of linq methods
int[][]. Just loop through and get all the elements
I need to return T[]
VS by default is a new line, vscode is the same line. A lot of web devs would use vscode so makes sense for js.
Yep. But would be preferrable if T[][] didn't exist in the first palce
Tip, you can make VS export an .editorconfig file that follows your code style, that will be put in the solution folder. Now everyone that clones the project will receive the editor config, and VS will override its settings to enforce the rules in the editorconfig file. Good when working with a team! EditorConfig is a standard and will work across most IDEs.
Braces on newlines is still the convention for C# though.
struct MyStruct<T> {
public T[][] myarray;
….
}
Yeah isn't that what microsoft recommends for C# ? new lines
List<Collider> colliders = new();
foreach (var (key, value) in colliderTypes)
{
colliders.AddRange(value.FindColliders());
}
return colliders.ToArray();```
you can even make your struct IEnumerable to loop through all of them
then just make an array of lists of colliders
i do not understand what us making this difficult tbh
What I posted is already an answer to what I asked
In complicated production code with long names, type constraints and lots of args, the { on its own line makes a lot of sense. Inline { is extremely annoying eventually. It gets lost in all the linebreaks you need anyway.
I do find Inline { hard to read
i have long names, and if I have to give my function declaration multiple lines, I can just give it its own newline manually
its like having an essay being double spaced vs not
former being more legible
while my IDE doesn’t fight me to insert a one line { for small methods
But that’s inconsistent and even more confusing
i don’t try to read the {
I read the indentation
i read the shape
i look at it, and it makes sense to me
That (indent) fails with complicated signatures
I don’t have a problem, even with 3 line function declaration
I just want the default to be almost no whitespace, so I can add as much whitespace as I want
VS and Rider have limits to what they can do format wise procedurally and often a separate line for brackets and braces saves the day
Consistency and clarity are much more important than tersity
i find both very important
Yes but if you have to chose, favor consistency
i go through regulatory documents for work, and some countries put the same information that fits in 2 pages into 10-15. It actively makes my job way more difficult. Even if the 10-15 pages is extremely consistent
you just need to scroll and scroll for what you’re looking for, and it drives me mad
That’s an anecdote that doesn’t relate
second one deff more legible even with vars on same line
it does relate. If you totally forsake tersity for consistency, you get a clusterfuck
but yeah at the end of the day is just preferences 😛
you need to balance
It sadly isn’t and this statement always comes up to end the discussion.
its like arguing:" I prefer to put a line in my 7 where some dont"
realistically, you are going to have a mix of many small function signatures, and a small number of giant ones. That is fact. You need to weigh both.
the only sane thing to do is to stick to the most widely used standard. It makes everything easier.
This, especially when multiple people work on the same code base
Your PR was rejected
Code does not comply to naming conventions
you know you can change { to your preferences by just pressing ctrl i, right?
if you have multiple people on a project, you will have different preferences
Hence why you must unite them into one
Your preference should be the widely used standard, then everyone has the same
naming conventions are more important than newline standards
Else you'll have commits from other team members with the description: "fixed formatting of XYZ"
Naming conventions are impossible to establish
You didn't use Git with a team did you
i mean naming for variables
conventions like camelcase, pascalcase, screamcase for consts…
to get good names you have to teach people a hundred things about patterns and what readable code looks like, which is very difficult
yeah you dont' wanna be the one doing private string sum
tfw you have a function name that is 60 characters long
at least we're not in the dark ages of character limit for vars
hence why abbrevation is ugly now days
I cringe when I see that still
Most overly long names are a sign or symptom of the author not structuring their code/module or not thinking about what they are doing.
i'm having some trouble with that right now
I have lots of state machines with unique states
LinearBossLocomotionMoveState is a mouthful:
- It's for the
LinearBossLocomotionlocomotion system - It's for a move command, so
Move - It's a state, so
State
you mean OnChestDictionaryCancelServiceRequested
I considered using namespaces
so that it's just be MoveState
but then I'd have 20 IdleState classes
Use namespaces and nested classes? Or use a keyed fsm?
although, I do rarely reference specific state classes outside of the context of sibling states
I mostly just reference EntityState everywhere
so maybe I will go back to namespaces again
You should never reference states outside an fsm IMO
Defeats the purpose
and instead trigger all state changes from within the FSM's states?
You would send signals to the fsm, the fsm is configured to perform the allowed transitions, states themselves are ignorant of other states and may only know what signal lead to them
Ie you separate transitions logic from state implementation
I have a manager that puts an icon over a planet on the screen, and it needs that planet's position. The planets have a PlanetController MonoBehaviour, and a PlanetData ScriptableObject. Should the icon manager script address the PlanetController script directly to get the position, or should it talk to the PlanetData scriptable object, which would have a function to get the planet's position from the MonoBehaviour and return it to the icon manager script?
i'm trying to follow a couple of tutorials for making an inventory system rn and they all seem to be based on drag and drop icons
does anybody know how i can make it into a sort of list system instead (where you'd just pick an item from a list, no crafting and no drag and drop), i can't seem to find any resources and i kinda need a nudge in the right direction
for reference this is what i mean
What part specifically are you struggling with? An inventory is just some collection of data (a list would be fine to use). Then the UI would populate itself based on the list of items
i'm mostly struggling on adding and displaying data
but mostly displaying data
like i said a lot of the tutorials spawn the items in a drag and drop system with a lot of icons already there
i want the items to just show up when you get them
Can I serialize non-primitive types like Vector3 in Sql when they are inside other types like Transform?
So I want to have a structure with position but I don't want to break it into 3 separate floats
with standard SQL you could only do that as a string
Could you recommend any other?
of course
The data can just be some objects under the content of a scroll rect. The items list can have some OnChange event that the UI script subscribes to, to be notified when the inventory changes
Will it work with types I create?
it can do, it supports the Blob data type which can take any binary data
but you should not need that, the system creates C# classes for you from the table definitions, you can extend these to do what you wish
hey, when i change a color the color sets to white, and if i just change a bit in the inspector it sets to the wanted color
Show how you're setting it, I assume you're setting values from 0 to 255 when it should be 0 to 1
Hey guys, I need a bit of help. I posted this in the wrong channel, #archived-game-design , but that's my issue so i don't double post it
example of playerpref recived (RGBA(0.349, 0.229, 0.104, 1.000))
Show the code for ParseColor(string). Note that color parsing will fail on system languages that do not use a dot . as a decimal separator for numbers, unless you explicitly handle it by passing an invariant culture both when saving and loading the color string.
For example, on a system that use a comma as a decimal separator, you will write (RGBA(0,349, 0,229, 0,104, 1,000)) and attempt to read it, leading in a failure if you split the string by a comma. You'll get 8 elements instead of 4.
would someone be able to offer an explanation as to why unity is destroying my serialized properties?
I have a few classes, most importantly a serialized class named Item (which is a POCO with the children Armor and Weapon which each have various children of their own) and a pickup class (mono-behavior put onto the player) which holds a reference to one of the children of Item.
The reference to item inside pickup is marked as [serializedRefrence, RefrenceDropdown] using this plugin: https://github.com/vertxxyz/Vertx.SerializeReferenceDropdown
Whenever I set the reference and start the game, I get this error:
any ideas?
Here is the code from pickup:
[SerializeReference, ReferenceDropdown]
public Item itemInstance;
private void OnTriggerEnter(Collider other) {
if (other.CompareTag("Player")) {
InventoryManager.Instance.Add(itemInstance);
Destroy(gameObject);
}
}
}```
This looks like an editor only issue, e.g. an issue with rendering the inspector
I imagine it shouldn't have any impact on gameplay itself
I am having slightly inconsistent results using a conditional to check
if (transform.hasChanged)
{ // checking faces of die }
else {
if(deltaTimeElapsed > 0.2) {
//assume die is finished
}
}
for a dice roll event, to make sure the die has stopped moving before getting it's side
in the else statement, that is where I consider it finished
Is there a better approach?
it works like 9/10 times or more, but sometimes the else's inner conditional just doesn't get reached at all
i guess if the roll was super quick, that would be the only situation that could happen so maybe i just need to make the time window a bit smaller, like 0.05s or something
doing that didnt fix it either 😦
dont really understand the problem in your code, can you give more context
that seems to be the case, thank you!
ok so nothing seems glaringly wrong? I need the time delta otherwise small pauses can be false positives. maybe i should try increasing the time elapsed, or it could be my time elapsed is off. i'll try debugging that part
yes but why are you doing it like this
idk is there a better way?
oh its probably due to my face detection algo
as to the why im doing it this way I mean
im checking the normals with dot products and stuff, not using any raycasts. its a pretty cool algo I borrowed from a youtuber
but because of this, i need to wait til the die stops moving
I mean, i'd think you need to do that with any solution to detecting the faces, but shrug
so on my school computer right it was talking about how i had the old event system or some shit and there was a button to import the new one, but on my computer its not saying that and the event system here is not the same as the one on my school computer
Why Rigidbody.sleepThreshold is not shown in the inspector?
float?
I'm talking about the Rigidbody component
The 2D version has in the inspector field to configure its sleep behaviour
But the 3D version doesn't
huh
How can I do this? It says either parameter or return type has to be the type I write it in
public static implicit operator Vector3((float x, float y, float z) tuple) => new Vector3(tuple.x, tuple.y, tuple.z);```
Do new Vector3(tuple.x, tuple.y, tuple.z)?
It's not what the question is about but thanks
3D physics team probably figured it would be too niche to clutter the inspector and pay the cost of (de)serialization.
You can only make operator for clases you made
You didn't write neither Vector3 nor (float x, float y, float z)
@orchid bane
Isn't there a way around this?
Yeah, you can wait a few years until C# 12 and do an extension cast operator
If you want something more immediate I would do an extension method instead
For the tuple?
Yes
Thanks
Trying to make a lightning strike spell when an enemy enters a trigger and the player hits a button, but it doesn't seem to instantiate the lightning strike at all
{
if (Input.GetKeyDown(KeyCode.F))
{
ButtonPressed = true;
}
}
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.gameObject.tag == "Enemy")
{
enemyPos = collision.transform.position;
if (ButtonPressed == true)
{
Debug.Log("Spell Pressed");
ButtonPressed = false;
if (LightningStrike == false)
{
Debug.Log("Lightning Strike initiated");
LightningStrikeInstance(enemyPos);
}
}
}
}
private void OnEnable()
{
playerControls.Enable();
}
private void LightningStrikeInstance(Vector3 enemyPosition)
{
LightningStrike = true;
instanceLightning = (GameObject) Instantiate(lightningStrikePrefab, enemyPosition, Quaternion.identity);
Debug.Log("SPAWNED");
StartCoroutine(WaitTime(2f));
LightningStrike = false;
Destroy(instanceLightning);
Debug.Log("DESTROYED");
}
public IEnumerator WaitTime(float waitTime)
{
yield return new WaitForSeconds(waitTime);
}
that isnt how coroutines work, the destroy should be in the coroutine
- Add logs on button press and on trigger stay. Does the execution enter there at all?
- That coroutine doesn't do anything.
Ohh ok that makes more sense
Holy cow that actually worked thank you guys!
How could I also make the lightning spawn a few increments above on the y?
you are passing the enemyPosition to the function, add to that vector
ah ok
Not exactly code, but:
Whenever I open a script on visual studio on my microsoft surface (windows 11) the filename is listed as "miscellaneous files" and not "assembly c#"
And the project is listed as having 0 solutions
Also the top doesn't have "attach to unity"
I have tried uninstalling and reinstalling visual studio and checking to see if I modified visual studio with the unity game design thing
!vs
If your IDE is not underlining errors in red or autocompleting code,
please configure it using the link below:
• Visual Studio (Installed via Unity Hub)
• Visual Studio (Installed manually)
follow this
👍
esp the workloads
it works now i just needed to put visual studio in the external script editor
thank you
I've been playing the the Graphical Stata Machine, and I got it to Invoke() Methods in an seperate C# script. Now I'm trying to get the C# script to access as Script Machine Variable. Does anyone have an example on how that's done?
I have 'using Unity.VisualScripting' and a have a bool boolName in the Variables component in the Game Object. But when I try to access it with 'scriptBool = (bool)Variables.Saved.Get("boolName") I get a Variable Not Found error.
Whoop. Found the answer. Instead of 'Variables.Saved.' it should be 'Variables.Object(this).' That works.
Why are you making an implicit operator for a tuple? 
Change (float x, float y, float z) tuple to Tuple<float, float, float> I guess
Though you should not do these micro managed pieces of code. It brings no quality.
What is the best way to handle this cast data.floor = newData as FloorData;
Classes are FloorData : BaseData, IConstructable NewData : StackableData, IConstructable
StackableData is BaseData though
StackableData : BaseData
So the data is compatible but I'm just not sure how to handle the casting? For context the reason NewData isn't base is that some building data can be stacked
Other classes
ColumnData : BaseData, IConstructable
PropData : StackableData```
It may fails in down cast: basedata to floor data
Newdata can be safely cast to stackable and stackable can be safely cast to basedata, but not all basedata are floordata so it may fail
If I cast to StackableData first, won't I lose the IConstructable data though?
Maybe for the time being I can do
PropData propData = (PropData)(newData as StackableData);
propData.buildStage = newData.buildStage;```
Aren't you basically asking for duck typing here?
not sure what duck typing is?
All I know is that I control the cast because it's a switch depending on the kind of job I'm doing
So it's like... I know that A will always fit into B, but it can't cast so I'm not sure how I cast it then
Looking into the duck thing and yes probably? I'll look into it more
C# doesn't determine type compatibility by their contents, but by actual types they implement
Yeh and because Stackable inherits from Base and the floor Inherits Base... I thought that'd make it compatible
So I can't cast unless it directly inherits from FloorData at some point, it doesn't matter if they both inherit from the same root Class?
I guess Inside the FloorData class I can just write my own implicit casting
Yea it can only be casted to those explicitly shared types
You can safely cast to base class (move to root) but down cast (move to leaf) may fail (not must fail)
Inheritance is tree structure
Well you could do terrible things with dynamic and/or reflection, but it's probably best to revise your design
Yeh the only issue I'll have is losing the interface data though?
I tried to design this to be flexible but it seems my design in general for things these days is just bad
Reached the point where I can have an idea and get it to function but it's been a bane because it doesn't mean I'm achieving anything well
I keep refactoring things because it's a mess and it just ends up a different kind of mess lol
Yea inheritance just tends to break down when you try to model these sort of complex trees.
So the data types was just a way I designed save data, all my tiles use it and it's been easy because I get the type of data and process it according to the type and can gurantee they have the data I need. That was the original design
Now I'm working on a job system which is tons of things that need doing like building walls, floors and etc and it's now crossing that over that seems to be causing this mess
I wanted to just be able to pass it to a cell and that just handle it accordingly, it was meant to be a clean design but I duno what's good or bad design anymore
public void Execute()
{
// Restore our preview back into a functional objects
PreviewManager.EnableColliders(newData.gameObject);
PreviewManager.RestoreMats(newData);
PreviewManager.ClearCollisionDetection(newData);
cell.InsertObject(newData, owner.placementID);
}```
Like this was meant to be good but I duno if I'm doing things right or wrong anymore and it's really messing with me
(It's a function in a Job class) which is 1 per thing that needs doing
Sorry.. Guess I'm just ranting at this point
Thanks for the help, I'll try and think of ways to improve on this
Hey, when I add a terrain to a gameobject like so: var terrain = island.AddComponent<UnityEngine.Terrain>(); and apply a terrain material and an alphamap, it works but the normals for the terrain layers don't show until I re-select the material in the inspector manually and I can't figure out why.
I have tried terrain.Flush() but without success.
So the issue is the material? Are you using HDRP?
If you are making changes to parts of a HD Material in unity (Like normals) it isn't actually updated manually, when you press it in the inspector the Editor reloads it
To update a material in runtime you use
"HDMaterial.ValidateMaterial(newMaterial);"
If you're using premade materials and not changing them, then I wouldn't know sorry
just use [serializeFields] for them no ?
and get the reference like that
Depends if you're dynamically updating materials or not
By that I mean like properties in the material itself
I hope the line renderer is perpendicular to the y-axis without looking at the camera. However, the lin renderer always looks at the camera. I tried to modify the alignment, but the child line is not displayed when I modify it from View to Transform-Z. How can I solve it?
Hi, is it normal that serializeField in my property drawer doesn't appear in the editor ?
I would like to avoid hard coded reference
I am using URP
How are you editing the normals? Are you changing them on the material?
No I am changing the normals on the terrain layer at runtime
hello! Does anyone know the behaviour of "is" or "as" for an Unity object when it's destroyed? Is it going to cast to null and/or return false or is it going to return the type?
I sadly don't know then sorry Ziptie 
hm ok
Do you have an example of how you use it?
When it's destroyed then the type of what you get should be null in general
It will still be considered non-null by those operators when destroyed
I think it can sometimes still return GameObject when destroyed though
If you do
Destroy(targetGameObject);
if (targetGameObject is null){}```Then targetGameObject is GameObject
if you destroy and then do
```csharp
if (oldGameObject is null){}```Then oldGameObject should be null... I think?
I could honestly be wrong though
Is null just checks if it is null without using == or !=, it doesnt try to cast it in the same way as doing is int otherwise itd pretty much always be true
my game's interactive objects are called SimObject, which are derived from MonoBehaviour, and when they are active characters, they are SimActor, derived from SimObject; there's a function that removes a SimActor from a spawned Dictionary by its id, but I check if it's a SimActor:
if(despawn.Value is SimActor simActor){
SimsMachine.singleton.OnActorDespawn(simActor);
}
"despawn.Value" is a SimObject
for some reason, sometimes "SimsMachine.singleton.OnActorDespawn(simActor)" is not called, so I thought it could be that "despawn.Value is SimActor simActor" evaluates to false because this function is called when the game reloads and the objects are actually Destroyed (which is done in an unordered way by Unity), but other stuff that happens outside the if clause still function normally.
My objects are not destroyed during normal gameplay, though, so the function is being called as it should; they are pooled.
But also just use == null
Yeh but doesn't it do a lot more in "== null" to check if a GO is scheduled to be destroyed and etc so that it's accurate?
using "is null" I think can be incorrect sometimes?
As bawsi mentioned
When you match an expression against null, the compiler guarantees that no user-overloaded == or != operator is invoked.
https://learn.microsoft.com/en-US/dotnet/csharp/language-reference/operators/is
Yes it can be wrong because it doesnt use == or != which unity overloads to do special stuff
Unity's destroyed check relies on overloaded operators, so you can generally check C# documentation whether a specific feature uses overloaded operators
hmm, so it'll evaluate to true. Now I think the problem might be other, then
thanks, I found the problem while analysing deeper because of your help. So the sim actor removal wasn't being called when the object was releasing its id, just when it was being unloaded. (There are two types of despawn in the game)
Generally, which is better to use - Coroutines or Asnyc methods?
some time they are not interchangable
if you can use coroutine then use coroutine, since some unity (async) api is designed based on it
coroutines are great for behaviour over time for scene objects because their lifetime is automatically tied to that object, otherwise async methods can do pretty much everything a coroutine can do and returning a result/handling exceptions is a lot easier
coroutines can also do unity-specific stuff like waiting for the end of the frame etc that async methods can't (without some extra code)
coroutine stops if gameobject destroyed but not async (i got NRE because of that)
How would you go about making a terrain system (2d)? I'm using squares for materials, but I'd assume it'd be inefficient to place each block one by one and it should use a mesh instead
But how do I do that so that both the shape and texture is right?
Or is it fine to use singular squares?
Depends on your game and the terrain, but usually you'd indeed want one mesh with either tilemaps or splatmaps.
Oh I forgot that existed
And how do I add a texture to it? Like when a different material is placed
Greenvision Devlog 1#
https://youtu.be/yThFiFbpOFE
This video is about the beginning of my game developement journey, would be great if you support me and the developemnet of the game. Pls sub!
Can someone give me feedback on my devlog?
To tilemaps?
Yeh
You don't add materials to a tilemap. You have different tiles with different sprites.
Okay Ima look it up
Thank you
How many c# laws do I break if I use new to hide variables/override in a derived class?
how dare you?
:(
naw, i think i did that before . . .
I can't use any more generic constraints, I'm digging this hole way too deep
i was going to say is it bcuz of generics?
I'm using OnEnable to load in a scene. i'm aslso trying to load specific scenes by referencing a JSON file with another class. The issue is that by doing this it causes a loop where when I load in a scene from the scenemanagement class it also loads in the datapersistence manager (with the onenable) in the second pic which causes an infinite loop. I suppose my question is that is there ether a different system I could use instead of OnEnable for scene loading or is there a known method to stop this infinite loop.
what's the situation?
There is ONLY ONE C# law. Thou shalt not have compile errors. The rest is left to your conscience
Generic slots, with generic storable types, with generic interfaces (which include their specific SO type)
I was using covariance but it's too much to work with
Basically, I had eliminated a lot of type checking, but it started created complications as I kept expanding the project.
a complete generic structure (architecture) to eliminate type comparison it seems . . .
do you need to check if the storable type is the same as the slot type?
I wanted to do like some MMO hotbar kind of thing, and it works pretty well, but I think I can eliminate a lot of code if I just type check a little instead.
it's not like I've that many types in general to make full use of covariance
are you using SOs to check the type? that's what i usally do . . .
Right, so how it is, I can always expect the type that is inserted into the slot is at least of a derived slot considering the type of the slot
I do have to type check currently if it's something more derived, but I think I could have optimised it a bit more
So the idea probably is something like this:
public interface IStorable
{
StorableSO SO { get; }
}
public interface IItem : IStorable
{
new ItemSO SO { get; }
}
public interface IEquippableItem : IItem
{
new EquippableItemSO SO { get; }
}```
It would eliminate a layer of my constraints and I can always expect an at least derived type
Why not use inheritance on the SO side and elimate the need for this?
Yeah, I got all the inheritance in parallel with each other. It's just when you have three layers of generics, you have to be quite type specific on everything.
can't each class implement the corresponding interface so they're not derived from each other?
so it has to be done on both ends?
public abstract class Slot<S> : where S : IStorable<IStorableSO>{}
public class ItemSlot : Slot<IItem<IItemSO>> {}
public class EquipmentSlot : Slot<IEquippableItem<IEquippableItemSO>> {}
public abstract class Storable<SO> : IStorable<SO> where SO : IStorableSO {}
public class Item<SO> : Storable<SO>, IItem<SO> where SO : IItemSO {}
public abstract class EquippableItem<SO> : Item<SO>, IEquippableItem<SO> where SO : IEquippableItemSO {}
public interface IStorable<out SO> where SO : IStorableSO {}
public interface IItem<out SO> : IStorable<SO> where SO : IItemSO {}
public interface IEquippableItem<out SO> : IItem<SO>, IUsable<SO> where SO : IEquippableItemSO {}```
This mess of a system
yes
@latent latch I thinks it's a good solution, looks unorthodox but does the job
If you like covariance, hey it works
this looks fine. i had smth similar, but i don't remember linking the interfaces to each other (i may have) . . .
interfaces are required for the covariance, but without covariance I can remove the generic binding here which is something I want to do
It looks like a mess but it saves you from a lot of redundant type casting which can only lead to cleaner logic code
Gizmos.DrawLine works in build ?
no
What I did is I made a variable a virtual property, and the child class overrides the property to send it to a constant
but you cant override its return type
which is my problem for my crappy solution there haha
why can’t you just make it a different function?
As in multiple getters for each derived type?
if the return type is different, that feels like just a totally different thing
so why are you trying to override
The getter should always return the most derived type of the SO is what I'm trying to accomplish
easily done with some generic constraints, but the complexity of adding more constraints upon it makes the compiler mad at me
I'm just not that proficient with generics
i feel like there should be an easy way to do that
maybe ask the C# discord
a generic is probably the way to go
i’m pretty sure you need something like: ChildClass : ParentClass<ChildClass>
Then ParentClass<TChild> {
and your getter returns a TChild
If you need multiple children accessible along the way, you probably need to define a non generic version for unity to workwith
The overall problem is how the slot itself is generic, and it contains a bunch of these generic types. The idea is if I can reduce a lot of the constraints that the slot is containing, then I'd have to be less type specific (but I'll have to cast more often).
But I'm trying to go half-way here and trying to figure out the best way to expect an 'atleast' derived type of an item contained in the slots
——Parent
ParentBase<TParent> { property returns TParent}
Parent : ParentBase<Parent> {}
—— Child
ChildBase<TChild> : ParentBase<TChild> { childimplementation}
Child : ChildBase<Child> {}
—-Grandchild
GrandchildBase<TGrandchild> : ChildBase<Tgrandchild> { grandchild implementation}
Grandchild : GrandchildBase<Grandchild>{}
something like that could work
just because Unity hates generics
under normal circumstances, those non base classes would not be necessary.
@latent latch let me know if that helped or not
This should also not change anything in the SOs that exist for the matching type
I expanded out my implementations to give you an idea where I'm at with my code.
Currently messing around with other implementations but I do understand what you're accomplishing there
There's just a lot more extra stuff going on with what I got which is making it trickier to implement something clean
out of curiosity, could you use a generic interface?
I am
does that not work?
It does work alright, but it turns a lot of my functionality very type specific. It's not awful, but it's such a headache to work with,
RaycastHit2D hit = Physics2D.Raycast(transform.position,transform.right, 1, mask);
vs
RaycastHit2D hit = Physics2D.Raycast(transform.position,Vector2.right, 1, mask);
not sure which I should be using
or even there is even a difference
is there a reason you can’t just return the parent type? like normal inheritance
Yeah, that's what I am doing currently with this non-covariant implementation I got and it requires taking the parent type and casting it when I use it. I'm just curious how to make this type of override getter without hiding the previous type, but I guess that's not really a thing in c#, or at least not without generics.
I pretty sure there's ways to do this in java, but it probably does something similar to redeclaring the type of the derive.
OOP is hard
transform.right uses the right direction relating to your transform, while vector2.right would give you a right vector of that in world space I believe, even though it's 2D I'd expect it to have a difference.
Well, I guess if you don't rotate your transform it wouldnt matter, and it's in the same system composition as world
from what I was reading they would both do the same thing and it wouldn't be in worldspace
Try debugging it and see if the values change
then rotate your transform and do it again
from my limited understanding, you can get the point of contact
from there you can probably determine that
collision.GetContact(0)
from private void OnCollisionEnter2D(Collision2D collision)
like Hawk mentioned, you can get the contact point, then use a direction from the center of the circle (as the reference of angle 0) to determine the angle of the contact point . . .
darn, can't actually test this because I change the X scale
instead of rotation 😄
If you dont rotate your transform then you're probably already aligned to world coordinates so yeah, it wouldn't matter then
yep, in which case both of them dont do as I want lol
so need to flip the way it faces depending which direction my "enemy" is facing 😄
EDIT: nvm I forgot that the ray stays for 0.2s so its just where enemy is moving from 🤦♂️
I'm hoping someone can help - I'm building a scene into an asset bundle, there's nothing in the scene except a room made out of simple cubes with a standard shader, some simple seats and a single spot light that's using baked lighting.
I bake the lighting then export the asset bundle and then download it in a different project and open the scene.
Once I do this I can see that the lighting is completely different - I can't for the life of me understand why!
I do believe this better fits in #💻┃unity-talk or #archived-lighting 🙂
Hi guys. I want to create a leaderboard that the player can enter their own name for a new high score. Any tutorial for that ?
multiplayer?
nah, just for a offline game
make a local database
A file can work just fine as well
simple json or som
I would probably just make an object that holds name/score
a list of highscores
and then a simple json to save it to
just make sure you obfuscate the file extention to keep the common folk from prying the file and changing values
i can get my head around displaying the names and scores, but how can i get the input for players name ?
like when people want to type their own name
InputField
likely achievements/rewards wouldn't be based on that but on the score that would be sent
so all they could change is the visual score
If I do Debug.DrawRay
that only effects performance when Im in scene view right?
or do I need to "disable" that code before doing play normally/building project
Debugs dont exist in the build, not sure commenting them out is required
Pretty sure they do exists in build. There is no ConditionalAttribute. https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.conditionalattribute?view=net-7.0
interesting... it does make sense considering now that I think about it.. Debug.Log still works in the build, I think I was conusing it with the Gizmos class, I don't think that one does get included does it?
also @thick socket
Hey i wan't to change the scene after a certain amount of time but starting to load it before so i used LoadSceneAsync but how can i change the scene after the X seconds?
AsyncOperation sceneLoadingOperation = SceneManager.LoadSceneAsync(sceneName);
yield return new WaitForSeconds(minimumLoadingTime);
//SceneManager.LoadScene(sceneName);
OnDrawGizmos will not be called in a build.
WaitWhile()
i think
I'm making my own rigidbody fps controller, and my player collider has a physics material with 0 friction, but when i stop running on the ground, my speed slowly decreases. Why? If i have no drag and friction, I should be sliding with constant speed forever
can't tell anything without seeing at least the code / setup
The new scene will be activated once the async is done
bout to rec a clip
Hello, is there any way to add a field directly on transform? E.g. myGameObject.transform.myField
how to avoid that? and do something like scene.load and scene.change
thks that's probably helpful
no, you will not be able to modify the Transform class. at best you can create extension methods for it. you cannot add other members
📃 Large Code Blocks
Large code blocks should be posted as links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/
https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To get C# formatting the first line should only contain cs or csharp.
Add a comment with a line number if there is an error message.
```cs
// Your code here
```
Do not share screenshots of code unless requested.
mb, it was mainly to show the interaction that my speed is slowing down. (and I have no code that would slow me down anyway) so this problem is more of a "why is my rigidbody character getting friction or whatever"
uh why is collider not on the main rigidbody
I see. Maybe that was a XY problem. I have to create an "ultimate name" for my gameObjects, I'll access them using that name. Also the player is able to change names of gameObjects that they've spawned already. Those are gameObject.name. What should my "ultimate name" be? A tag? Guess it's weird to create a new tag for every gameObject. Also it's not that good to access the name using their class ItemBehaviour.itemName ?
wtf is an "ultimate name"
like, a unique identifier?
"final name", "unique name"
exactly
you need a key.
sounds like you need a GUID
I suppose you could attach an Identifier component to objects that need such an ID
a guid?
and then store a GUID or something similar in it
so Zombie is a "unique name" and Larry is a name (that is changed by the player)
maybe that's not what you want, then
explain what you will use this name for
I don't see friction. I see it slides when you let go
did already ?
You said you will "access them" using this name
oh, I see
you really didn't though
but then you said that an object's "unique name" will be Zombie
That doesn't sound like a very unique name...
Do you mean that this name is supposed to tell you what kind of object it is?
so every zombie has that Zombie name
i don't see Zombie as unique. that's just a category for organization or placement . . .
but, you see my speed decreases
sounds like you want to set up prefixed and suffixed names for objects . . .
I use those names to find them in items lists, for example
public T GetItemByName<T>(string itemName) where T : ItemBehaviour =>
items.First(w => w.name == itemName).GetComponent<T>();
(well, it's Component.name for now, that's what I have to change)
So each item in your game will have a specific "kind", like "knife" or "bomb"
even if you renamed it to "stabby object" or "mcbomb"
what do you mean? Guess it's a unique? All Zombies have name "Zombie" by default, so it's a "default name"
yes
a "unique name" would be different for every single object
hence why a few of us brought up things like GUIDs
yeah, a default name, like a specific category. that part is not unique . . .
no
ok, the problem was that the ground did not have this physics material too. Is there a way i can just apply the material to my player and not have to add it to every singe other 3d object in my game?
unique means one-of-a-kind. there will be no duplicates . . .
sounds like every item should have an Item component on it that holds the category
not for every single object? Why? There can be lot's of default Zombies, also player can name all of them "Larry"
"unique" means "not duplicated"
if you have two things named "zombie", then "zombie" is not a unique name
yeah, it sounds like you’d want a unique identifier
sorry, read as "ultimate"
then they won't be unique from each other. how could you tell which zombie is Zombie Larry from one another?
i don't see a clear meaning for "ultimate name"
that's why I suggested "kind"
"zombie" is a kind of thing. You can have lots of zombies.
yeah seems like they just want a default name that matches the category of the thing
public static bool ReferenceEquals(Object objA, Object objB);
what I do is I have a singleton EntityLedger. Whenever I spawn something new, I entityLedger.RegisterNewEntity(newGameobject).
I also call entityLedger.LogDestroyedEntity(object) whenever a logged object is destroyed
ok, let's call it "kind"
but you were checking by their names in your method. if they're all the same, how do you know if you grabbed the correct one?
RegisterNewEntity adds the entity to a giant list of all spawned entities, asks to issue a new serial number, maintains a dictionary of SerialDict[gameobject] = its serial#, and returns that new serial number
this way, every entity can have a unique serialnumber tied to it.
Well, I have just implement renaming functionality. Now I have to divide "kind" and name given by the player
before it wasn't an issue, as they all had names like Zombie, Knight, Wall 1, Ground 2
name given by player should be decoupled from gameobject name
gameobject name can depend on player’s name, but not the other way around, or you will run into issues
Anyone know if I can use c# reflection in webgl?
but how do I find Larry there?
yes
see if this helps
as we mentioned before, give each object (entity) a guid and use that to check for a specific object. this allows the user to rename objects the same if they choose . . .
Bro i literally joined your discord yesterday lmfao.
considering using your sql package for an mmp
cool, welcome
mmo*
do you want the output to be unique?
bro im so dumb lol
the output? You mean no 2 Larries?
how did i skip that 😂
because if the player names 2 zombies larry, you can’t return larry. You need to return a list of zombies named larry
works perfect, thanks
so isn't it better to have a ItemBehaviour.itemName instead then?
sounds not as complicated either?
that’s kind of what I do
you can see relevant restrictions for the different platforms/scripting backends here: https://docs.unity3d.com/Manual/ScriptingRestrictions.html
so that's the issue
you need to decide what you want it to do before we can help you do it
only if the itemName is different for every item. if two are the same you won't know which one is chosen when checking the registry (collection) . . .
I think you should first figure out what defines an item.
what makes a knife different from a spoon?
do you want to allow multiple Larry, or allow finding a unique zombie named larry? The two are mutually exclusive
do you have a ScriptableObject class that each item holds a reference to?
public TResult SpawnItemByName<TResult, TData>(TData data) where TResult : ItemBehaviour where TData : ItemData
{
TResult itemBehaviour = GameManager.instance.GetItemByName<TResult>(data.name);
TResult result = Instantiate(itemBehaviour.gameObject, data.position, itemBehaviour.transform.rotation, environment).GetComponent<TResult>();
result.name = data.name;
return result;
}
Thanks!
this code spawns an item by name. So it spawns Zombie prefab if item's name is Zombie
no
I see, actually I don't need a specific item, so.
so the name is just a key to find a reference to prefab?
yes, exactly
so the key needs to be unique?
yes
can’t you just make a dictionary then lol
no multiple Ground -> Ground 1, Ground 2 instead
Dictionary[key string] outputs prefab object
sure, that's almost exactly what I've done, the list of structs to be sure, as Dictionary isn't serializable
What I do for this is I have an SO named BuildingObjectBase. This SO has a field for the prefab it is tied to. BuildingObjectBase also has a field for TileBase, which is a tile in game it is tied to.
At the start, I have TileDirectory go through all the BuildingObjectBase to make a dictionary where tilebase goes in (the key), and BuildingObjectBase comes out.
During runtime, I go through all the tiles in a tilemap with GetTile(). I look in the TileDirectory dictionary for that tile, which gives me its BuildingObjectBase. I do some logic to know if I need to instantiate the prefab, and if yes, then I access the BuildingObjectBase’s field with its associated prefab
The difference here is you use a string instead of a TileBase. The difference doesn’t really matter
I see, I go through children of #Environment GameObject
But you absolutely want to organize those intermediate SOs.
does it solve an issue with naming gameObjects?
to their names don't matter this way?
It depends on what you are going for
My BuildingObjectBase also has a field for saveName, which is a string I can use to search for it.
yeah, I have told it here
When TileDirectory makes its big dictionary at the start, it also Debug.Asserts that all names are unique. If I accidentally gave 2 things the same name, it will give an error.
so is it more efficient than having ItemBehaviour.itemName field?
and getting it through item.GetComponent<ItemBehaviour>.itemField
this'll the a unique way then
it is similar, but you want to protect that SO
my whole BuildingObjectBase is basically immutable. Nothing should be allowed to fuck with it.
yeah, but it's more logic to implement, and it can be bad of performance guess ??
well, I just have to make sure that I won't call'em the same way
my entities all have a SpawnedEntityHandler, and that SpawnedEntityHandler has a field for the BuildingObjectBase it is tied to
just loop through them, and make sure they are unique, dude.
ain't it too much for a simple logic ? 🤔
or just check if manually
assuming you are going to have a very large number of items in the game
if you have like 4, it doesn’t really matter
but if you actually have a full game system that revolves around it, you want the error checking
I see, yes, I can check it in the start, for sure
debug.assert string is not already in dictionary, right before you add the string to the dictionary
Still guess just an itemName field for the parent class of all items'll be enough.
enough until everything crashes down, right?
problems should be solved when they appear.
If you have a very large number of unique items, you will want to make an intermediate SO to hold them
this way you can just drag and drop the whole list or whatever, without ruining everything accidentally
I have BuildingWheels, which mostly just have a List of BuildingObjectBase. I can make my TileDirectory take in a list of BuildingWheels, and then search in each of them
This way, instead of my inspector having one list with 300 different entries, I have like 10 SOs, each having like 30 entries each, and the TileDirectory having a list of those 10 SOs.
Otherwise, you will never find anything in that gigantic list when going manually
folders..
i don’t mean in file directory
I mean my TileDirectory object.
It is a function of BuilderWheels, and just loops through every builder wheel, for every item in the wheel…
what do you mean by TileDirectory object? in the game?
yes
My TileDirectory is an SO
With a different Singleton monobehaviour that sets it up. Although, I could have made it a regular behaviour, maybe. That is do not destroy on load
My tiledirectory SO has like 3 fields that I load in inspector which are effectively immutable during runtime. It then populates a bunch of dictionary fields based on that input. Could have used a monobehaviour, tho
yes, you could've...
but the intermediate wheels should be SOs
it’s a lot easier to reuse an SO than a behaviour. Especially as an inmutable container
by SO you mean ScriptableObject, right?
yes
guess it's redundant in my case, as Items are just behaviours with their own scripts
I did a lot of that while I was still learning, so I had to wrestle with a bunch of nonsense with SO fields changing differences between build and editor
in retrospect, I should have made TileDirectory a singleton monobehaviour
it’s very quick and easy to make SOs that just store a collection of other SOs anyway
so basically, create a CategorySO that holds a list. each CategorySO can be a different category of objects. place your individual SOs into the list of their respective CategorySO . now create a DirectorySO that holds a list of CategorySOs and place each CategorySO into the list. the DirectorySO will have a method to iterate each CategorySOs list to add their items to the main dictionary . . .
exactly
If I just want an Enemy to change the Ondestroy in EnemyBase do I have to make a new class to inherit from EnemyBase just to override that one function?
or is there a better way to do that 😄
well, if you want to write custom code, then yes, you need to write it somewhere
Everything in my game depended on my DirectorySO, so I had to make a monobehaviour singleton to hold quick access to that SO, have it set up the directory on Awake, and give it super high priority in script execution order.
bad wording question...meant more...can I just add another script that overrides it
You could add a UnityEvent to EnemyBase that's invoked when the enemy is destroyed
or do I have to inherit
Oh, you're using Unity's functions
thats what I was looking for thanks!
Unity messages do not care about virtual methods.
always forget events are a thing 😄
Can't you make OnDestroy virtual though and override it?
Hi how do i fix that my player can move diagonal its a 2D Topdown
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
//Animations is here
}
void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
that’s what I would do
yes but I don't really want to create a new class to override it just to change Ondestroy
well, I shouldn't say that specifically...
would rather add 1 small additional script to the object
When a Unity message is sent, it invokes the method with the matching name on the component
So if EnemyDerived declares a method named OnDestroy, it doesn't really matter if it's an override or marked new or neither
That method is getting called.
What you might wind up doing is declare a HandleDestroy method that's virtual
and then override it in child classes
the alternative is to put a bool you can check to change the behaviour of OnDestroy
call it from OnDestroy in EnemyBase
EnemyDerived.HandleDestroy would be invoked, and you could call base.HandleDestroy() to let the original EnemyBase.HandleDestroy method run
code starts to get long and messy that way
just adding event and new class entirely is much cleaner
how many different options do you have for OnDestroy
so the player should not be able to move diagonally?
Are there any resources to better understand how to read the profiler. I have parts of my game that drops frames but I have so many objects doing their own thing I'm not sure what I need to try and optimise, going through them one by one will take ages.
and ik of at least 2-3 of them that will be different ondestroy stuff also
whether its spawn 2 of a smaller enemy on death
or 7
Yes and idk what function to use insted of rb.MovePosition
You would still use MovePosition.
compare the x and y values and set the one with a lower magnitude to zero
and the OnDestroy is not on a derived class, but a separate component?
Mathf.Abs(foo) < Mathf.Abs(bar) tells you if foo's magnitude is lower than bar's
no Ima add another class that basically just waits for an event that fires "OnDestroy"
then do logic there
But like what is bar?
yeah, it sounds like you need dependency injection there
because you aren’t trying to do something ondestroy. You’re trying to do something else
okay and why does that work? and is it in FixedUpdate or Update?
well, consider what it means if you move in both the X and the Y axes at the same time..
it will go in 0
what? it will move diagonally.
Oh yea
how do we detect if a child is added in unity?
i would like to know if there is a function about that
There's this:
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnTransformChildrenChanged.html
You can also just know because presumably your code is adding the child
I think what you need to do is make: interface IEnemyDestroy, and an EnemyDestroyController : Monobehavior (or somethig) that has a serialized field for IEnemyDestroy. In EnemyDestroy’s OnDestroy, it calls the IEnemyDestroy’s interface method.
i am gonna check that
ty
That is probably a much cleaner solution to Hawk’s problem.
What does Mathf.Abs do?
oh hey, neat
didn't know about that
In my game, I have a class called SpawnedEntityHandler, which handles anything that is supposed to be super generic for anything that can be spawned. That sort of Monobehaviour is where I might put that sort of gating thing
no I just need this
public class Spawn2Minis : MonoBehaviour
{
EnemyCharacter enemy;
private void Start()
{
enemy = GetComponent<EnemyCharacter>();
enemy.EnemyDeath += SpawnMinis;
}
private void SpawnMinis(EnemyCharacter character)
{
}
}
is there a way to detect that for the scene?
and detect the name of the child?
with ```cs
public event Action<EnemyCharacter> EnemyDeath;
.....
EnemyDeath?.Invoke(this);
that’s another way to do it. Depends on how generic the behaviour is, and if it is on all your enemies or not. or just on enemies of a certain type
Oh ok so it makes sense -numbers to +numbers like PosNumber = Mathf.Abs(NegativeNumber)
i think your EnemyCharacter monobehaviour is the same as my SpawnedEntityHandler
I see, if I feel that everything is messed up and I ain't finding no items, I'll implement this
it probably is, I'm gonna reread your messages if my game'll be constantly crashing
thank you both your help and explanations, I really appreciate this 😄❤️
what are you trying to accomplish
A CategorySO will help you not get lost in your own files
I'm not getting lost right now, so..
If you have 300 items, you will
then I'll consider implementing this stuff
if all your enemy SOs are in one category, and all the items in another, and players in another, it will make it a lot easier to find everything.
This is assuming you have 1 entry for every individual little thing you add
Where do i ask for tilemap help
#💻┃unity-talk probably or #🖼️┃2d-tools
unless its code related
Is there a debug.ray but for boxcasts?
thinking boxcast is best for determining if my "feet" are touching ground
i made my own static class to draw several lines to make boxes, and Xs, and triangles…
don't worry i just found the fix
i am using mirror but i found the is a function in the networkmanager that detect when a player join
also you should try using Gizmos, becsuse DebugDraw has some oddities because of how many frames it shows and all that.
That was a major XY problem then 😵💫
That's why I asked what you were trying to do
XD
any chance you could share that? 😄
if not it wont take me long to make anyway
Is there a way I can tell the compiler that a virtual method MUST be called by overriding methods? I just switched something from abstract to virtual (because I realized there was a common use-case). It was easy enough to add the base calls, but it'd be nice if the compiler had my back there
Obviously, you don't always need to call the base method, but it'd make sense as an attribute or something for when you do
Stick with abstract and wrap the call around the required behavior
public void DoTheThing() {
DoSomeRequiredThing();
DoAbstractBehavior();
}
protected abstract void DoAbstractBehaviour();```
Ah, that's a good idea.
I've done exactly that in a few other places.
Although, that's a bit awkward if C derives B derives A
I guess B would define its own abstract method and call that
The use-case here is an "init" method. The base class just needs to store a parameter into a field. Deriving classes want to do actual setup work in there.
Yeah that should fit with the pattern
(if only i could do this in a constructor)
boxcast2d
when doing that it starts with a point
is that point the middle of the box
or the topleft?
I'd expect so.
or top-middle?
origin is more ambiguous
It would be very awkward if it wasn't the center.
It's the center
it's the direction the box is cast in
that's the direction the box flies in
a "cast" is like throwing the box through the scene
interesting
(in a straight line)
It's not like you're doing a box-select
I though raycast just drew the line from start->fin and its the same for boxcast
where you draw a big rectangle enclosing the start and end points
note the difference between this and OverlapBox/CHeckBox which just checks a single box shaped area in the scne
yes.
it moves the box's center from start to end
raycast is like throwing a dimensionless point through the scene
boxcast is throwing a 2d box through the scene
I think you're imagining this.
and by box it means a square?
RayCast sweeps a 0D object (a point) through the scene
LineCast sweeps a 1D object (a line) through the scene
BoxCast sweeps a 2D object (a rectangle) through the scene
actually LineCast and Raycast are the same
oh, it's Linecast, not LineCast
dies
oh dammit I got that mixed up again
It's so plausible sounding
I don't actually do 2D, see... 
the only difference between linecast and raycast is whether the second param is a direction vs a position
Casts a line segment against Colliders in the Scene.
it's a way to go
It sounds right, too!
would require multiple raycasts so thought boxcast might be better
I'll get this right eventually
what would you recommend doing 😄
from what I've found is the way you recommend is typically better than what I think would work best lol
would you just do 2 raycasts "down" at the "edge" of feet?
depends on the game
was originally just doing a collider...but that doesn't seem to be working great because of ontrigger enter/exit
boxcast is generally pretty good
so boxcast is like sending a box through space down
in whatever direction you specify
would a "linecast" where I draw a line thats the length of the feet
be better to "send down"
yeah, it's not actually sweeping a line. I was mistaken.
for boxcast I understand choosing the "length" to be the size you want to collide
e.g. "i want to cast a ray from point A in direction D with a length of L" is a raycast
For a linecast it's
"I want to cast a ray from point A to point B"
(that sounds really useful, though)
how do you want to pick the "height" of the box though?
there's no length, but there is a "distance" which is how far to throw the box
I mean for the "size" of the box
it doesn't matter much in this use case. basically should just be smaller than the player
length x height box size and then send it down a little to see if grounded
so like I might want 2 length, 0.00001 height and send it down 0.2 to see if it hits ground
BoxCast has:
origin: where the box's center starts
size: the width and height of the box
angle: the rotation of the box
direction: which way the box moves
distance: how far the box travels in that directions
size is the only thing that decides how big the box is
you still sound confused by what the boxcast is actually doing
if it makes it easier you can also use a Boxcollider to visualize /adjust size in the scene and use it as size params for boxcast
makes sense for 3d
size determines how big the rectangle is
for like 2d
I'm not sure how this works in 2D. In 3D, casts with volume (e.g. SphereCast) will ignore colliders they start inside of
That's the main thing that comes to mind.
regular rectangle vs simple compact rectangle
A couple reasons:
- if you move it in a diagonal, or with a rotated box, the box corners make a difference.
- 2D casts can hit things at the start of the cast.
not sure how the 2nd part matters since it would just hit it anyway even if not at the start?
but hadn't thought about the first part
figured that wouldn't change much vs just rotating your "line"
was just using a BoxCollider2D
is using that as a trigger vs checkbox much different?
might just use boxcollider2d still and iterate through all the "contacts" instead of "ontrigger"
with a trigger collider and OnTriggerEnter2D you have to wait until the physics callback
you also don't get any contacts
physics queries can be used immediately
👍
triggers are horrid for this usecase, I just use it to set my size for my checkbox
var grounded = Physics2D.OverlapBox(groundedCheckCenter.position, groundedBox.size, 0, ~ignoredGroundedLayers);
seems odd that checkbox just returns true/false
you're either hitting something or you're not, its very primitive sometimes is enough
tbf its all I need so it works nicely also
~ignoredGroundedLayers whats this mean? never seen ~ used before
its the opposite
it ignores that layer
ah cool...why ignore a layer vs find only the ones you want?
do you have the trigger like disabled you just grab the size from it?
its just a trigger, i probably could
idk if it would throw nre
havent touched this project in ages(it was for jam so was non-issue optimizing wise) 😅
Im seeing "Collider2D" doesn't have a .size
you need box because different colliders have diff props
like circle has no size
but radius
maybe I shouldn't be using a capsuleCollider lol
why not?
cause the size might be slightly different using OverlapBox and a capsulecollider as the thing that shows size 😄
i use capusle with box and works ok
not sure why its shaking in scene view sry
this img shows you were using boxcollider not capsule for the feet
yeah player is capsule , ground check is box
a circle would probably fit a capsule bottom better but box was sufficent for me
doesn't seem to error for me when I disabled it
as long as its referenced iirc you can still use disabled component props ig not 100 on it
the checkmark only disables the unity events iirc
you sadly can't see it in the debug screen if its disabled
guess I'll disable in code lol
draw a gizmos to view my box
private void OnDrawGizmos()
{
if(!Application.isPlaying) return;
Gizmos.color = IsGrounded() ? Color.green : Color.red;
Gizmos.DrawCube(groundedCheckCenter.position, groundedBox.size);
}```
I mostly just need to view when creating the box to make sure my "base" collider doesn't overlap it making the box not work 😄
yeah i used the gizmo only for debugging visually if my Grounded worked
collider looks fine, althought your .right seems to be off, unless you're in world pivot mode
fixing that rn
collider should be centered...it wasn't before lol
but only because its not on a child that gets flipped
😅 that too
what doesn't work?
ohh thats something else? is the raycast for what
moving too fast and missed the collider I guess lol
i have no idea what's going on in this image
its a photo of you Fen 😄
basically raycast in front so right before they hit a wall they switch direction and run other way
and which part isn't working
and a raycast down so if they are about to "fall" off a platform they dont
is that short red horizontal line the raycast?
it looks like it's starting inside the wall
raycast skips every couple frames and it by the time it "enabled" again the raycast was inside the wall
how often you raycast?
should have been moved back a little so if it "misses" the wall first time around it will hit even when collider is against wall(the nose/wolf is running into wall)
every other FixedUpdated
figured bad performance and no real differnce other than switching frames a few frames earlier
makes a pretty big difference trust. also raycasts are pretty cheap, you'll be fine
well, it turns out the "real difference" is that your game breaks...
what if something not static jumps infront of it
it will intersect stuff and seem poor reaction, probably not good Ux
well it only turns around when hitting walls/platforms
you don't have moving obstacles or doors that open/close ?
granted yeah its only a few fps differnet running each frame vs 30fps
so might as well use it max fps
how many agents did you have running that many raycasts though lol
If you're gonna go with every other fixedupdate, at least make the raycast longer
about 5-6 AI cars
so many raycasts now lol
I had hundreds of objects with 3 raycasts and it was fine
But that was a test and not much else going on!
gotcha thanks
whats ur debug.drawray time lol
I made slightly longer and moves it back a little so even if it breaks it still catches it and turns around
.2s
looks like barcode scanner
yep lol
just changed a ton of colliders to raycasts
wish that was something I knew I should be using earlier
surprised none of the youtube videos used them when I was first learning
moved almost everything over except my bullets
not totally sure how to calculate how far forward my raycast should be so I dont miss a collision while also making sure it blows up in the right location
since my bullets aren't slow but aren't super speed
I don't know if it is the right place to ask the question so sorry beforehands 😅
#💻┃unity-talk is for basic non-programming Qs
Ok, I will post it there 🙂