#archived-code-advanced

1 messages ยท Page 69 of 1

pseudo onyx
#

Also, i dont understand why if the dot product is greater than 0, it means the character is facing left, and if the dot product is less than 0, it means the character is facing right

sly grove
#

IDK seems really overcomplicated. I would have just done this:
private int FacingSign => (int)Mathf.Sign(transform.forward.z);

sly grove
#

it checks if you're facing forward or back

#

if you want left/right then it's private int FacingSign => (int)Mathf.Sign(transform.forward.x);

pseudo onyx
#

ok thanks

pseudo onyx
# sly grove it checks if you're facing forward or back

When I use this line of code:
private int FacingSign => return (int) Mathf.Sign(transform.forward.x)
I get the following error "The type or namespace transform could not be found"
'Cowboy.Sign(transform.forward.x)' must declare a body because it is not marked abstract, extern, or partial

sly grove
strange blade
#

Im sorry if this isnt in the right section, I wasnt sure where this would go. Im trying to enter play mode faster, and Ive already messed with the enter play mode settings. My scene has a fairly large object pool, but other than that its basically empty.

Why is unity calling SaveScene() everytime I enter playmode? I already saved my game, I dont need it to do that. Can I turn this off? I have failed to find any information about how to control this or why its even called when I press play.

brisk spruce
#

I think it's gotta save so the scene editor is synced with playmode

strange blade
#

I dont think I understand why it would need to sync the two though, as no changes are really made during play mode and everything should be pre-set for testing via the editor

brisk spruce
#

I don't think saving a non-dirty project should have any impact either though

strange blade
#

Im hoping im wrong with this, but I ran into an answer on Unity:
https://issuetracker.unity3d.com/issues/editor-unselects-elements-when-entering-and-then-exiting-the-play-mode


One of these edge cases is with prefab instances, which were not getting fully backed up to disk even though they were dirty. This mistake was causing them to be different when coming back out of playmode, and also causing their selected state to not be properly restored.

Unfortunately, for historical design reasons that we are now somewhat stuck with, this optimization cannot work robustly, so we have decided to remove it.```

If im understanding this correctly, it sounds like.. I cant avoid it? As unity used to actual have a ignore save button..
sleek terrace
#

anyone know why my shader produces no color whatsoever? It seems makes the entire image invisible

#
Shader "Unlit/test" {
    Properties{
        _MainTex("Main Texture", 2D) = "white" {}
    }

        SubShader
        {
            Pass {
        
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                #include "UnityCG.cginc"

                struct appdata {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };

                struct v2f {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                };

                sampler2D _MainTex;

                v2f vert(appdata v) {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = v.uv;
                    return o;
                }

                fixed4 frag(v2f i) : SV_Target {
                    fixed4 col = tex2D(_MainTex, i.uv);
                    return col;
                }

                ENDCG
            }
    }
}
grave fossil
#

why texture = ((DownloadHandlerTexture)request.downloadHandler)?.texture; returns me null even if data is not null and it is correct ASTC image?

hardy sentinel
sleek terrace
gleaming rock
#

How should I do packet delta compression when player position data is sent to clients via UDP?

So far I am thinking of creating custom packet for each client per tick of all player positions (delta compressed)

But that is O(n^2) operation and with just 32 players would result in 1024 iterations per tick (timed and on my pc it is about 2ms per tick)

Currently my code is something like (called every tick and is Unreliable packet)


void SendPositionUpdateOfAllPlayers()
{
  // create message
  // add every players' position to the message
  // send the message to all clients
}

This works fine except I don't want to send non changing state of players or projectiles.

Should I use job system with burst for this or would it even work with riptide (to build messages in jobs)

Or maybe send states as reliable packet every second and send deltas relative to that (simple approach but doesn't yield as great bandwidht savings)?

azure moss
#

whats the best way to make manual animator transition?

#

think of it transition without condition in animator. animator will play animation automatically after end reached or sometime before it

azure moss
#

you might have a situation where player isnt in your view

#

server or p2p implementation?

gleaming rock
#

Dedicated server

plush hare
#

and the server computes the delta based off of that.

#

You'll need to variable width encode your values, and quantize your floating points before packing the data together.

#

You can use a bit flag to denote whether a state has changed or not.

#

that's about all there is to it.

gleaming rock
#

@plush hare thanks. However what im worried about is iterating players with O(n^2) complexity per tick to build the delta compressed packets

plush hare
#

Test it in a build. Not in the editor.

#

Your game server should only be running one core anyways, so jobs is of no use

#

if you're lucky, burst will SIMD your stuff. Otherwise you'll be writing your own AVX2 parallelized code

gleaming rock
#

I tested on il2cpp development build on windows

#

2ms per 1024 iterations

plush hare
#

yeah thats a lot

#

sounds like you're doing something wrong

gleaming rock
#

Assuming 32 players

plush hare
#

thats too much time for 32 players. you're making a mistake somewhere

gleaming rock
#

Alright I will debug

plush hare
#

actually depending on the CPU, that might be a reasonable time frame. It's 4 in the morning and my brain isn't working rn

#

30hz should give you about 33ms per tick

#

again, your server should only be running one core per instance. Sometimes it hurts performance to try to parallelize everything on to different cores

gleaming rock
#

Yeah I was hoping that burst could optimize the nested loops

plush hare
#

The only real recommendation I can give right now is to just make sure you've got nice linear data

#

minimize cache misses

#

make it nice and predictable for the hardware prefetcher

gleaming rock
#

Okok

tropic stag
gleaming rock
#

@plush hare Appreciate the help. Not sure what I was doing earlier, now I'm getting now about 0,15ms per tick

wet burrow
#

What's the best place to talk about packages?
I created a custom package that I can download from GitHub into my project using the package manager (which I'm super pleased with) but I want to make custom classes in my actual project that inherit from one of the base classes in the package, yet it won't recognise the namespace so I can't reference those scripts in my project.
Thoughts on how to deal with this?

flint sage
#

You got to create an AsmDef and reference the one in your package

dusty wigeon
#

Stop cross posting...

wet burrow
flint sage
#

Then your class has to be private otherwise it would work

tropic stag
#

coming from a programming background I spent way too much time trying to figure out a good way to do something instead of just making a game... I implemented a state machine using components subclassing monobehaviour, and when switching states I just set enabled = false on the prev state, and enabled = true on the new one. Instead of abstract state enter and state exit behaviours I just use onenabled and ondisabled.. is tnere anything wrong with this approach?

flint sage
#

If it works, it works

plucky laurel
#

to it wont have a true "state enter" event

sly grove
brisk spruce
#

Forces you to make your own type of async event args and async subroutine to bind to, it's a pain

white pulsar
#

i'm currently implementing A* on a grid based aproach. currently my system obtains the nearest available node from the start position and the world position by converting the world position to a grid cell

However, my code is a bit faulty, as it seems to be shifted a bit, i'm unsure what's causing the shifting itself
https://hastebin.com/share/jeturohuti.java

#

the hastebin itself contains what i've done so far, sure its a bit cut down to avoid sharing the entire class, but it should contain the general idea for it.

#

the issue is basically that the GetNodeIndexFromPos is nnnot really working as i expect it to, considering the fact that its shifted as the picture above shows

#

apologies if this isnt precisely the correct place to ask, i've never triedd to implement A* until recently and it seems a complex topic :b

brisk spruce
#

Could you circle a "expected" vs "actual" in that pic

plain abyss
#

I have a 3D environment made out of runtime-generated thin-walled meshes, and I want an orthographic overhead view to display those walls as lines. I have a line renderer as a child of the meshes set to have points along the vertices of the mesh, set to only be visible to the overhead camera. This allows the overhead camera to see the "walls" with the line renderer despite them being vertical planes (First image shows this working as expected). This works fine for simple shapes like squares, but for more complicated shapes it forms a lattice of lines across the vertices (Second image). I want to only outline the "outside" of the mesh, but I can't use bounds because some of the meshes are angled or circular and a box is not always the best fit. How could I determine the outermost edge of vertices in a mesh to pass to the line renderer, or, barring that, is there another way I can display lines where flat vertical planes would be?

white pulsar
brisk spruce
#

Or is it 3rd party?

plain abyss
brisk spruce
white pulsar
#

here's a still pic with the grid itself showing, the white wireframes being the available grids for the algorithm

brisk spruce
white pulsar
#

no, all objects are at the root of the hierarchy

brisk spruce
#

Or the uh, whole grid object parent

plain abyss
white pulsar
#

sorry, the GameObject AStar has both components, the AStarNodeGrid and the Pathfinding System

#

while the End and Start game objects are the ones i'm using for testing purposes

#

doing a search of localPosition on my project doesnt reveal anything, so i doubt it's that specifically, might be with the method i wrote that should transform the world position to node index

torpid smelt
#

Alright, quick one. is there any way to see what the full function name is there? this is in a profiler window which is zoomed in all the way, and I need to know what's getting called here

#

naturally I can't zoom in any more

sly grove
sage radish
torpid smelt
#

No & No, unfortunately. Gonna see if I can find it now in the hierachy

sage radish
torpid smelt
torpid smelt
torpid smelt
#

2020.3.21f1, coworker found it on a previous frame. thanks for the help

#

fucking photon

sleek terrace
#

Does anyone know why my the default custom unlit shader isnt working with tilemaps?

sleek terrace
#

figured it out, it seems by default tile maps are facing backwards, thus you have to set shaders setting "Cull" to off

sleek terrace
#

How is that even possible?

#

Im generating at most 25 objects

#

Funny, but every time I instantiate the object, its instantiates itself...causing the start to be called, causing more instantiating...

#

๐Ÿ™‚

shadow seal
#

Ah, recursion

sleek terrace
#

wait, that shouldnt occur tho

#

because, Im not instantiating the hexgridmap object

#

If I instantiated the Hex shape in HexGridMap, should the instantiate call the Awake and Start methods in Hexgrid map?

sturdy frost
#

how IJobEntity get nativeThreadIndex

sleek terrace
untold moth
warped pasture
#

Hey, is there a way to draw a batch of Sprites in a performant way?
I need to have some graphical image between each tile division in a hexagonal tilemap, some sort of "wall", that may or may not appear depending on some gameplay rules.
I know this kinda sound vague but I looked at Graphics.DrawTexture but it doesn't seem to work on Update or take camera into account and I need something that can be zoomed in and out too. Did some research around and couldn't find a satisfying solution and I'm worried about spawning a hundred sprite renderers in a scene for a WebGL game.

long ivy
#

are you doing something that breaks batching? That would be the easiest solution. If your image uses the same material and texture (or textures are packed into the same atlas), you can manipulate sprite geometry directly to avoid extra renderers

warped pasture
storm tartan
#

Hi! I am searching for a tutorial to make a dynamic blocking animation system for melee combat. I want the hand and the sword to be positioned according to the collision point, by using Two Bone IK Constraint and other dynamic bone components. Any recommendation or info about this context?

timber shadow
#

Where do people go to talk about unity's localization package?

spare violet
#

Unity forum has a dedicated localization section. One of the Unity devs is quite active there.

urban warren
#

Right, so I am doing some reflection for a editor tool, and running in to an issue with events.
There is an event that takes a internal class as a param. I need a property from that param class, and I need to be able to subscribe and unsubscibe. So I can't just use a lambda to 'convert' from one to another.

internal class UnityParameter
{
  public int foo;
}

public class UnityClass
{
  public void Register(Action<UnityParameter> action);
  public void Unregister(Action<UnityParameter> action);
}

This is the method I want to add to pass as a parameter to the Register and Unrigster methods.

public void MyCallback(int bar);

Any ideas?

#

All that is coming to mind for me is to have a 'converter' method. And a static dictionary of Dictionary<UnityClass, Action<int>> which the converter method calls maybe. And I subscibe MyCallback to the action in the dictionary.

#

That feels really ugly, so I was hoping there would be a nicer way...

flint sage
#

Generate some code that takes UnityParameter and casts it to object (or gets the field or w/e) and calls your function

flint sage
#

Linq.expressions for example

urban warren
#

Ahhh

flint sage
#

Or Pure IL

#

Or abuse one of the InternalsVisibleTo assembly names

urban warren
#

Shoot I gotta go re-re-re learn/brush up on expression trees, but that seems like a good way to do it! Thanks!

flint sage
#

It's not that difficult for such a simple case

#

And you can find examples

urban warren
#

Yeah I remember seeing examples of it.

flint sage
#

If you got until monday I can send you a similar example ๐Ÿ˜›

urban warren
#

I just don't use them enough, so how exactly to build one starts to slip my mind.

urban warren
flint sage
#

๐Ÿ˜‚

urban warren
#

All this just to support SerializedProperty array binding in UITk

urban warren
flint sage
#

Maybe

#

Does that matter

urban warren
#

Unfortunatly

#

I might be able to go without, not sure how Unity will handle it

flint sage
#

Uhh

#

You might be able to get a methodInfo from it and assign that

#

and use that to unassign as well

urban warren
#

Hmm, I think that would be the same thing

flint sage
#

Tbh, I'm not sure on the details of assign events reflection

#

You can always set it to null

urban warren
dusty wigeon
urban warren
dusty wigeon
#

You are trying to directly register to a SerializedPropertyBindEvent event which has a T of UnityParameter ?

urban warren
dusty wigeon
#

Maybe you could somehow instantiate a System.Action<UnityParameter> with Activator.CreateInstance through getting the type by Reflection.

dusty wigeon
#

You cast pointer of function to other type.

urban warren
#

I guess I could do void MyMethod(object evt) instead. But that passes the responsibility of getting the property off to the method itself.

dusty wigeon
#

With the use of maybe Convert.ChangeType.

urban warren
#

Basically I want to create a extension method void RegisterPropertyCallback(this VisualElement element, Action<SerializedProperty> callback)

dusty wigeon
#

You can define the extension itself ? What is public void MyMethod(SerializedPropertyBindEvent evt) in relation to this extension ?

urban warren
#

That is not possible due to SerializedPropertyBindEvent being internal. So I would change it to public void MyMethod(SerializedProperty property) and pass it to the extension method as the callback

dusty wigeon
#

So you want to convert public void MyMethod(SerializedProperty property) to something like public void MyMethod(SerializedPropertyBindEvent evt)

#

While SerializedProperty is a field of SerializedPropertyBindEvent

urban warren
#

Other way around

#
internal class SerializedPropertyBindEvent
{
  public SerializedProperty Property {get;}
}

This is not possible as SerializedPropertyBindEvent is internal.

visualElement.RegisterCallback(MyMethod);

public void MyMethod(SerializedPropertyBindEvent evt) { }

So this is what I want to do.

visualElement.RegisterPropertyCallback(MyMethod);

public void MyMethod(SerializedProperty property) { }


public static void RegisterPropertyCallback(this VisualElement element, Action<SerializedProperty> callback)
{
  // Somehow register the `callback` to the `RegisterCallback` and get the `Property` value from `SerializedPropertyBindEvent`
}
dusty wigeon
#

I'll look at it latter if you want to continue the conversation.

urban warren
#

Sure thing, thanks

plucky trellis
#

I've been trying to use a compute buffer in a URP render pass for a while, but no matter what, it always generates a memory leak, or other problems, no matter how I use it. (For reference, the buffer is of a fixed size, known at compile time) Instanciating in the pass constructor, and destroying it when the parent render feature's Dispose() method seems to leak (why?). Creating the buffer in the OnCameraSetup() method, and subsequently destroying it every frame in OnCameraCleanup() doesn't leak at least, but the created buffer doesn't seem to function (why?)

#

Is there any advice on how to go about this?

dusty wigeon
# urban warren ```cs internal class SerializedPropertyBindEvent { public SerializedProperty P...

It seems to me that you want three things.
1- Create a System.Action<SerializedPropertyBindEvent> that invoke a Action<SerializedProperty> with the property inside the Action<SerializedProperty>.
2- Register the newly created System.Action in RegisterCallback(System.Action<SerializedPropertyBindEvent>);
3- Have the capacity to unregister the previously registred event.

For the first part, I believe you can simply create the required System.Action through the usage of Reflection with Delegate.CreateDelegate. There is multiple example online that seem plausible that could potentially be adapted to your need.

The second part should be pretty easy if you have a little knowledge about Reflection.

For the 3rd part, you will need to either use a Dictionary to hold the conversion between Action<SerializedProperty> and System.Action<SerializedPropertyBindEvent> or return an object to represent the newly created derived which you would be able to use to unregister.

class Program
{
    public static void Perform<T>(T value)
    {
        Console.WriteLine("Called = " + value);
    }

    public static Delegate CreateAction(Type type)
    {
        var methodInfo = typeof (Program).GetMethod("Perform").MakeGenericMethod(type);
        var actionT = typeof (Action<>).MakeGenericType(type);
        return Delegate.CreateDelegate(actionT, methodInfo);
    }

    static void Main(string[] args)
    {
        CreateAction(typeof (int)).DynamicInvoke(5);
        Console.ReadLine();
    }
}

https://stackoverflow.com/questions/12131301/how-can-i-dynamically-create-an-actiont-at-runtime

urban warren
#

haha funny enough that is actually what I was asking if there was a way to avoid (the dictionary I mean)

dusty wigeon
dusty wigeon
urban warren
dusty wigeon
#

If you find a way to map System.Action<SerializedPropertyBindEvent> into Action<SerializedProperty> directly without instancing an intermediate you could, however I doubt it is possible.

urban warren
#

Yeah, too bad you can't do like an implicit conversion for delegates like you can for structs and classes. Guess that would feel a bit cursed though haha

dusty wigeon
#

Maybe the dynamic keyword could be use there. I've yet to experience the full capacity of the this particular keyword.

urban warren
#

Yeah nor have I, though it could be a possability

dusty wigeon
urban warren
onyx blade
#

is there a difference in using actions in a list, or defining a delegate to fire?
Are there significant things I should be aware of?```cs
namespace Utils
{
public class Timer
{
private float _currentTime = 0;
private float _maxTime = 0;

    private List<Action> _actions = new();

    public Timer(float time, Action a)
    {
        _actions.Add(a);
        _maxTime = time;
    }

    public Timer(float time, Action[] a)
    {
        _actions.AddRange(a);
        _maxTime = time;
    }

    public void Tick()
    {
        _currentTime += Time.deltaTime;

        if (_currentTime > _maxTime)
        {
            _actions.ForEach(x => x.Invoke());
            _currentTime = 0;
        }
    }
}

}

sly stag
#

No need for a List. A single Action variable should be subscribable as a multicast delegate, in just the same way you'd subscribe to an event

#

ie _action += MyMethod

onyx blade
#

oh

#

oops

onyx blade
#

much appreciated

sly stag
#

No worries

#

That one took me a bit to discover too!

onyx blade
# sly stag That one took me a bit to discover too!

if only there was a way I didnt need to use Update to make it tick xd ```cs
public class TimerController : MonoBehaviour
{
private List<Timer> _timers = new();

    private void Update()
    {
        foreach (var timer in _timers)
        {
            timer.Tick();
        }
    }
}
#

altho tbh, one update loop for all my timers isnt too bad

sly stag
#

Yeah, one update loop is not bad. I wouldn't get worried about the overhead of using Update unless you've got 100+ gameobjects in the scene using it at a time, in which case it's time to use some sort of manager for it

onyx blade
#

some form of frustum culling based update checker might not be bad ๐Ÿค”

#

make a scene updater behaviour that updates a bunch of others from its Update, based on if they are visible in the camera.
can reduce everything into a single update loop haha

#

actually, that sounds like an interesting idea, albeit heavily scope creeping

sly stag
#

Just because things are off-screen doesn't usually mean you don't want them to do anything

onyx blade
#

true

celest depot
#

Hello guys. I dunno why I get this error message from my unity project. Each time I install the 2D package in my project, the burst one make this error message

brisk spruce
#

@urban warren whats your end goal for your efforts above? It sort of looks like you are trying to do Event Delegation

swift orchid
#

@onyx blade you can also use Asynk or Coroutine instead of Update. And also you can do not call it each frame it is to expensive. You can call it each millisecond for example.

onyx blade
#

or am I missunderstanding something here?

urban warren
onyx blade
#

I do understand the use of the coroutine here, as I can just infinite loop a coroutine and work from there

#

with the whole WaitForSeconds logic

swift orchid
#

Ye, do infinite loop as coroutine or as Async but maybe update is the same result.

onyx blade
#

iirc, a coroutine has an update loop going on in the background.
dont quote me on that tho

#

I vaguely recall reading about that somewhere

swift orchid
#

"wouldnt calling it in update be more efficient than every millisecond given update runs dependent on the framerate?" about this one

onyx blade
#

ah

swift orchid
#

Did you read my answer I deleted?

onyx blade
#

yeah i did

swift orchid
#

nice sry I typed message then acsidantely delet it

onyx blade
#

no worries

swift orchid
#

I think Update the same as Looped Asynk or Corroutine you can use any option.

onyx blade
#

I also do kinda think im getting into optimization that may be irrelevant. still good to know.
but the difference in performance is most likely negligable, especially for my usecase.
im not planning to have 500 timers xd

#

if I have like 10, I tihnk I just about covered things

sly stag
#

Async functions can't call Unity API, so they're not a replacement for Update, and Coroutines run every frame so are no performance improvement (and they also have a tendency to make code messier)

#

Don't make up performance issues. Unity provides you with the best profiler in the industry. Identify bottlenecks through profiling, then address those.

#

The idea isn't to make a game that maximizes performance, the idea is to finish a game...if you waste all your time blindly looking for things to micro-optimize, you will not release

stiff hornet
onyx blade
#

for exactly this reason, and the reason that I suck at doing art and need to rely on others that may or may not help

sly stag
#

Yeah, it's easy to get caught up in, premature optimization can lead you down interesting roads, it's easy to put in weeks of work only to realize you've gained just a few milliseconds

#

That said, shameless self-plug, here's my solution so people don't have to go down that path with Update:

onyx blade
#

when people ask me what I do, I used to say game developer. now I say tool developer most of the time.
I build tools I will need to make a game, and never finish the game

onyx blade
sly stag
#

Damn, 6 years ago, I need to update that repo

onyx blade
#

im just gonna star that for later, I dont need it (yet) but it is VERY interesting

#

I must say @sly stag im a big fan of your website xd

sly stag
#

Thank you! The design was fun to put together

night drift
#

Anyone know how to add animations to this code

onyx blade
night drift
#

Like idle animations and walking animations

sly stag
#

Fancy!

onyx blade
# sly stag Fancy!

the dog is an actual native 3D element btw! not a game engine of any kind ๐Ÿ˜„

fresh salmon
night drift
#

My questions is getting flooded by the guy with the mw2 pfp

fresh salmon
#

And you're breaking the server rules

onyx blade
#

bruh

#

im going to assume gifs in general are a no-go right?

fresh salmon
#

<@&502884371011731486> Shitposting

onyx blade
#

well, meme gifs*

night drift
#

Are you serious rn?

night drift
fresh salmon
#

Yeah not sure how that gif went through

night drift
#

Its a gif of a goofy cat

#

Chill

onyx blade
#

server rules are here for professional conduct...

#

they exist for a reason

fresh salmon
#

No gif here lol, have you actually read the rules?

#

I mean you broke two in less than a minute, so that probably means no

night drift
#

Well your being very rude

#

SO uhh

#

Thats harrasment right there

onyx blade
#

@fresh salmon lets not feed the troll and let one of the mods handle the situation

hushed fable
#

@night drift Read the rules and quit spamming the channel

night drift
#

Im not spamming

#

It was one gif

#

Dont ban me tho

night drift
fresh salmon
onyx blade
#

casually going to drop that I dont like unity's animation controller

#

xD

fresh salmon
#

You don't do it all from the code. Setup an Animator controller with transitions and parameters, and control said parameters from the code

night drift
#

Yeah

#

I did that but

#

wAit

#

no

fresh salmon
#

Haha

night drift
#

It looked like this

onyx blade
#

ok that was pretty funny ngl

fresh salmon
#

Recording a video of yourself breaking the rules, very smart, especially when mods can see deleted messages

night drift
#

It was a GIF OF A CAT

#

Please

#

Ill leave this as soon as i fix my code

#

I simply want animations

sly stag
#

Is this some sort of weak blackmail attempt?

night drift
#

FUCK
FUCK

fresh salmon
#

They pasted the wrong video yeah

#

Lol

night drift
#

Huh?

fresh salmon
night drift
#

I did it

#

But i looked glitched asf

fresh salmon
#

Repost later then

onyx blade
#

I was about to say, that doesn't really change the difficulty of your question

sly stag
night drift
#

Yes

little sluice
#

I want to copy pixel data from one texture to another.
But not in a rectangle area, but in a triangle. Any smart ideas for that? In Winforms i would use a GraphicsPath and in Halcon i would use a region to limit the domain, but Unity Texture2D does not have that. Anything similar?

onyx blade
#

or is the Texture the only input

#

if you know the triangle's points, you can itterate the pixels and figure out where stuff is using the same principles for mesh collision detection ๐Ÿค”

#

if you dont know the points, I have nothing to offer.
but im very curious how to solve that

sacred dew
#

yeah that's kind of a nightmare to do, there are algorithms for looping over triangle areas in a 2D context, but nothing I know from the unity API.

onyx blade
#

I would think the only real way of doing it is to check if its inside the triangle or not and doing something based on that information. by simply checking the pixel coordinates in relation to the triangle

#

which, depending on the resolution of the texture, could be a fkn performance nightmare

sacred dew
#

so you only iterate the pixels you need

onyx blade
#

could you also um

#

generate a triangle mesh?

#

like

#

if you take the square you have and the triangle,
you could use the texture on a square.

if you then slice the the triangle from the square,
n the above case you would get 9 or so triangles.
then you search the vertices that are not part of the triangle and remove them
then you sample the triangle from the texture according to the UV's and the resulting texture is what you need

#

thats probably way roundabout of doing it, but im weirdly interested in seeing how that performs

little sluice
little sluice
brisk spruce
#

is there any quick and easy way to just show a small widget for each of these points for my script, in the editor? Just like a single dot or whatever should be plenty, at global world position

onyx blade
#

it has a function like start and update on monobehaviours, which you can use for editor only drawing of stuff

brisk spruce
#

perfect, this looks exactly like what I need, thanks!

onyx blade
#

not a problem! I'm currently debating whether or not I need tk define a grid for my game or just manually place the tiles. considering they don't change placing them is fine, but it would be much easier to drag them into a grid they snap into or generate them via code...

brisk spruce
#

Does this logic seem sane? I think its working

Dictionary<Vector3, HashSet<Vector3>> Waypoints = new();
private void TryAddWaypoint(in PolygonCollider2D collidor, in Vector2 from, in Vector2 to)
{
    if (Waypoints[from].Contains(to))
        return;

    var closest = collidor.ClosestPoint(to);
    if (!(to == closest))
        return;

    Waypoints[from].Add(to);

    if (!Waypoints.ContainsKey(to))
        Waypoints[to] = new();

    TryAddWaypoint(collidor, to, to + Vector2.up);
    TryAddWaypoint(collidor, to, to + Vector2.right);
    TryAddWaypoint(collidor, to, to + Vector2.down);
    TryAddWaypoint(collidor, to, to + Vector2.left);
}
#

trying to not only get all the points but track the connected From/To points as a dictionary of Point -> ConnectedPoints, should make doing the shortest path stuff easy later

onyx blade
#

oh man, I'm not the best at pathfinding... I bought an asset to specifically avoid having to do it xd

brisk spruce
#

code above is purely just to pre-cache the list of all the points contained inside the collidor

#

and their points they connect to

#

ah shoot I need to do 8 directions not just 4

onyx blade
#

depends on if you need diagonals, but I assume so

brisk spruce
#

yeh I do :x

#
TryAddWaypoint(collidor, to, to + Vector2.up);
TryAddWaypoint(collidor, to, to + Vector2.up + Vector2.right);
TryAddWaypoint(collidor, to, to + Vector2.right);
TryAddWaypoint(collidor, to, to + Vector2.down + Vector2.right);
TryAddWaypoint(collidor, to, to + Vector2.down);
TryAddWaypoint(collidor, to, to + Vector2.down + Vector2.left);
TryAddWaypoint(collidor, to, to + Vector2.left);
TryAddWaypoint(collidor, to, to + Vector2.up + Vector2.left);

that outta do er

onyx blade
#

yeah that looks like all 8

#

I think the initial logic looks fine at a glance, hard to tell from my phone to be certain tho

tall ferry
brisk spruce
#

Aight so I think I almost got this, but my value for a var I am storing the lines in for the gizmo to read off is is becoming null inside of OnDrawGizmoSelected

#

I currently just have it declared as a private variable on the class, do I need to apply an attribute to it or make it public or something so it actually persists? Im guessing atm its being treated as ephemeral by the scene editor

tall ferry
brisk spruce
#

Im seeing even Waypoints is considered null though using a complex getter/setter, lets see if I can just function with it being a normal public var and just calc the lines on draw

#

nah its still null

tall ferry
#

well when is waypoints being set

#

please dont share extremely cropped screenshots of code, it really shows nothing

brisk spruce
#

SuperTiled2Unity has "post processor" scripts you can run to manipulate game objects, so I add this component to one of the output game objects and set Waypoints on it

#

I dunno if there is an easy way to make a Dictionary serializable in the editor but the data should be getting set, prior it was just a list and the list was populated post import in the scene editor

#

but it just gets set like so, pretty straightforward

var waypointComponent = grnd.GetComponent<WaypointData>();
waypointComponent ??= grnd.AddComponent<WaypointData>();

waypointComponent.Waypoints = Waypoints;
#

oh I think I have an idea of whats different, I think because Waypoints (local var) is declared in the scope of the Import script, its dereferencing once the import script finishes

#

I need to instead do this, to make a new list and fill it with the contents of the Import scripts one so it doesnt de-reference...

#
waypointComponent.Waypoints ??= new();
waypointComponent.Waypoints.Clear();
waypointComponent.Waypoints.AddRange(Waypoints);
#

nope nevermind that aint it, still null

tall ferry
brisk spruce
#

anywho

#

does the value need to be actually serializable for OnDrawGizmosSelected to use it, and if it isnt it is null in that context?

#

Cuz I did a test here and added a string field, and then I set it right after I set Waypoints in the same spot, and then hit a breakpoint inside of OnDrawGizmosSelected annnd...

#

the string (which is serializable and shows up in the editor) does have its value, but the Dictionary (which is not serialized and shown in the editor) is treated as null

#

so Im guessing I need a serialized one?

tall ferry
#

no OnDrawGizmosSelected has no requirement for the variables being serializable, your Waypoints is just null in the editor since no code like awake/start has ran

#

although you are just showing somewhat random snippets, its hard to help. I dont know your system so most of the code shown really means nothing to me, since i dont know when its ran

brisk spruce
placid ocean
#

because its set in inspector

brisk spruce
#

it got set in the same way

#
var waypointComponent = grnd.GetComponent<WaypointData>();

if (waypointComponent == null)
    waypointComponent = grnd.AddComponent<WaypointData>();

if (waypointComponent.Waypoints == null)
    waypointComponent.Waypoints = new();

waypointComponent.Waypoints.Clear();
waypointComponent.Waypoints.AddRange(Waypoints);

waypointComponent.DidIGetSet = "Yes";
#

the fact DidIGetSet has a value of Yes there means this code did indeed succeed in setting it

#

My gut says this has to do with serialization or something, because thats the only difference I am seeing between the two

tall ferry
#

is it serialized in the inspector now?

brisk spruce
#

it also was working earlier when Waypoints was a List<Vector2> and not a Dictionary<...>

#

And List is serializable but vanilla Dictionary is not

brisk spruce
tall ferry
#

so therefore its set in the inspector.

placid ocean
#

why do you not justcreate new Dictionary inline

#

and check

brisk spruce
placid ocean
#

public Dictionary<Vector3, Hashset<Vector3>> Waypoints = new Dictionary<Vector3, Hashset<Vector3>>();

#

then it wont be null, just empty.

#

Im not sure if unity will cache waypoints added at editor time to dictionary

coral schooner
#

Nope

thin mesa
#

correct, unity does not serialize Dictionary by default. there are assets that can do it (or fake it), but unity itself can not

placid ocean
#

There you go

#

Or use a List of structs if in doubt (for gizmo anyway)

brisk spruce
#

not hard to fix though, just gotta use one of the SerializableDictionary extensions

coral schooner
#

Just populate the dictionary on initialization with Linq

brisk spruce
tall ferry
#

the issue isnt with it being serializable, its just that the data does not exist yet because your code hasnt ran.
notice in this example, i did not make my class serializable

coral schooner
#

Gizmos don't require any serializable data

brisk spruce
#

so of course it wont be null

tall ferry
#

that is exactly my point..

#

OnDrawGizmosSelected does not require serializable

brisk spruce
#

make it null/empty by default and then set its value via an importer script

coral schooner
#

Can you post the full code? I'm curious why this is an issue

brisk spruce
# coral schooner Can you post the full code? I'm curious why this is an issue

this code is being run inside of an importer script that builds the component during import of a custom asset (SuperTiled2Unity stuff)

var waypointComponent = grnd.GetComponent<WaypointData>();

if (waypointComponent == null)
    waypointComponent = grnd.AddComponent<WaypointData>();

waypointComponent.Waypoints.Clear();
waypointComponent.Waypoints.AddRange(Waypoints);

waypointComponent.DidIGetSet = "Yes";
#

and then the component itself is literally just

public class WaypointData : MonoBehaviour
{
    public Dictionary<Vector3, HashSet<Vector3>> Waypoints = new ();

    public string DidIGetSet;

    private void OnDrawGizmosSelected() { ... }
}
#

I had that before, if the importer code creates the dictionary, then its value is null inside of OnDrawGizmosSelected

if I default it to empty so I dont need to set it in the importer, it is en empty dict in OnDrawGizmosSelected

#

but interestingly enough, the value of .DidIGetSet does get set there and it is present inside of OnDrawGizmosSelected

#

only difference between the two is one is serializable and the other is not

placid ocean
#

I think youre right, it wont populate waypoints as it cant be serialized?

coral schooner
#

in AddRange(Waypoints); what is Waypoints in that context? KVPs?

brisk spruce
#

only difference between the List and the Dict is one is serializable and the other is not

tall ferry
#

yes because unity saves its value in the inspector, so it is not empty/null. My example was pointing out that OnDrawGizmosSelected does not require the data to be serialized. The reason Waypoints is null is because its not saved by anything

brisk spruce
#

Im pretty sure now if I just swap to a serializable dict this will start working

tall ferry
#

as that will save the values in the inspector, yes

#

but if you change something from Waypoints, you'll need to have it adjust the values in the inspector or the draw gizmos wont be updated since itll still be referencing that

brisk spruce
#

aight, so far so good, but looks like collidor.ClosestPoint isnt working quite right D:

#

ah I think I see what is going on, its offset by a bit yeah, aight

tired fog
#

Is 370 kb of data on a command buffer too much in unity?

#

Or would it be better to separate that into multiple command buffers?

sage radish
tired fog
#

Not sure, but many, It's a recursive function that assigns it, good thing, sometimes it weights 120Bytes, and sometimes 380Kb

#

A rough count, 1228 commands for weight around 31.6Kb

#

So, a rough count, for that picture I sent there might be around 14620 Commands

#

๐Ÿ˜…

#

Well, on the frame debugger I have this

#

for 31Kb

exotic trout
#

Hey @brisk spruce, Little late to the party but as someone who also had Waypoint related stuff in a dictionary I just wanted to +1 AYellowPaper's - Serialized Dictionary package (It's free). I've used a ton of third party implementations of serialized dictionaries ("Odin Inspector", "SerializeDictionary", "Serialized Dictionary Lite") but AYellowPaper's is by far the best experience i've had. Your mileage may vary though ๐Ÿ™‚

brisk spruce
exotic trout
#

Other cheap or free versions just felt a little clunky with their inspector implementation and odin inspector's implementation doesn't support use in prefabs

stark crag
#

I'm just getting started with DOTS, I created a subscene that has items on a little island in my scene, it is set to Auto Load, on startup the objects all appear, but I'm not seeing log messages from one of my scripts in the subscene (I am debugging why it isn't spawning a GameObject, so I added Debug.Log onto its Awake / Update methods, but not seeing anything). I'm sure I am doing something wrong, but I don't know what.

north marsh
#

If I spawn several un-awaited Tasks to modify a list should I put locks on the list?

Is lock ever needed in Unity tbh?

brisk spruce
#

but you should be awaiting the Task at some point somewhere

devout coyote
tiny pewter
#

no await then it runs synchronously and you are read-write the list, you have to lock the critical section

north marsh
brisk spruce
#

if it errors or breaks itll just silently fail

#

but it will still silently fail but in an async way XD

north marsh
brisk spruce
#

and I have only the smallest inkling of why they magically "just work" and Ive been using them for years

north marsh
brisk spruce
#

something something Task Manager Engine or whatever

brisk spruce
north marsh
#

Ok, and it is not related to Unity's running everything on main thread?

brisk spruce
#

unity doesnt run everything on a main thread, just uh, most of things

#

but as soon as you use Tasks (correctly), it is inherently auto-magically multithreaded

north marsh
#
List<int> lst = new List<int>(){1,2,3,4};

async Task modifyLst() {
    //remove first element
    //add it to the back
}

void Start(){
    _ = modifyLst();
    _ = modifyLst();
}

So I am for sure getting 3, 4, 1, 2 in this case?

brisk spruce
#

nope itll be a race condition

tiny pewter
#

no

brisk spruce
#

they wont error, but it will be random

#

or wait sorry in your case uh

north marsh
#

why would this be race

#

you just said task won't interleave with each other?

brisk spruce
#

itll be a race condition for which fires first but each task doesnt have any awaits in them, so youll still have them do their individual tasks one then the other

tiny pewter
#

i have said you are read-writing the list and you havent await (wait until previous one finish)

brisk spruce
#

so your end result will be the same, but which one did the first step and which did the second technically is a race condition but its very likely to be A then B

brisk spruce
#

the reason is purely because you're function is Idempotent

north marsh
#

yes

brisk spruce
#

such that A then B produces same result as B then A

#

if however you modified it slightly to have this:

async Task modifyLst() {
//remove first element
// wait 1 second
//add it to the back
}

then you'll have a variety of results

tiny pewter
#

the execution order maybe first task remove first->interrupt->second task remove then insert->first task insert

north marsh
#

wait 1 second as in thread.sleep?

brisk spruce
#

dont use thread.sleep for Task stuff, really dont need to use it at all anymore, Tasks and coroutines replace thread stuff

north marsh
tiny pewter
#

actually i believe even you await 1000 the result is still random the interrupt maybe occur before the first one remove

brisk spruce
north marsh
brisk spruce
north marsh
#

oh yea ture

brisk spruce
#

youll notice in Visual Studio if you have async but no awaits within, it greys out and gets underlined as a warning

north marsh
#

For context I am spawning four players in a for loop.

Don't really care who spawns first, but I do use four unawaited tasks to spawn them, instead of awaiting one to spawn then spawn another. Task has await inside because it needs to load addressables etc.

But inside the spawning task I do have to access a common resource (list of spawnpoints).

#

That's why I asked.

north marsh
brisk spruce
north marsh
#

what about nested tasks. Is result still deterministic?

My understanding is yes, because the two runs of ModifyLst still cannot interleave.

List<int> lst = new List<int>(){1,2,3,4};

async Task ModifyLst() {
    //remove first element
    //add it to the back
}

async Task Wrap(){
    return await ModifyLst();
}

void Start(){
    _ = Wrap();
    _ = Wrap();
}
austere jewel
#

You need to await every Task object you create

#

else you are going to eat any exception that gets thrown in one

tiny pewter
#

oh i mess up, task without await will run senquentially

brisk spruce
north marsh
austere jewel
#

use async void

#

but you also need to actually put the Task on a thread unless what you are waiting does that already

#

because it won't do that on its own

brisk spruce
brisk spruce
# austere jewel use `async void`

do coroutines keep their stack trace/errors intact? async void drops everything and messes up your stack trace something fierce, makes debugging and break points faceplant

austere jewel
#

Async void works fine in Unity

#

Any exception thrown in one is thrown to the Unity runtime and logged as usual

#

Outside of Unity I would not advise it

north marsh
austere jewel
#

No

north marsh
#

spawn that many coroutines, then?

#

but if a function is async void then you cannot await it at all.

That's fine for fire-and-forget only (which is what I asked for) but I sometimes do want to await for them and I dont want to make a second async Taskfucntion with exact same code

brisk spruce
#

Honestly both seem equally annoying but what can you do, such is the life of coroutines :x

brisk spruce
austere jewel
#

yeah I usually would go MyMethod, MyMethodAsync

austere jewel
#

(it's sometimes a practice to append Async to every task-producing method)

north marsh
#

I kept doing void DoTask() => _ = DoTaskAsync(); in the past.

#

okay ty so much

brisk spruce
#

yeah dereferencing a Task can cause bad things to happen, better to async void wrapper it

#

Spooky Garbage Collection At A Distance

north marsh
#

feels like I never truly learnt C#

#

lol

north marsh
flint sage
#

Yeah but it's not recommended since it'll swallow exceptions

north marsh
#

I thought async void won't swallow exeception, and exception swallow happens only when you dont await a Task?

#

nvm, it does still swallow exception

#

then there is no point to use async void wrapper

#

_ = DoTaskAsync() does the same thing

fresh salmon
#

Yeah it's the Task that contains info on whether an exception was thrown. No Task, no report

compact ingot
#

any exception in the DoTaskAsync above will be handled as a top level, unhandled exception by unity, the exception only gets swallowed if DoTask were to return a Task an that task was not awaited

north marsh
#

I gave it a shot and it seems it still swallows exception.

fresh salmon
#

Might be a Unity quirk, but in a regular app, DoTask swallows as it can't be awaited

compact ingot
#

yes, it only works because unity catches everything

#

it leads to people writing terrible async code just because it works in unity and never learn to do it properly

#

if you want to write somewhat proper async in Unity (that makes the hackery explicit), use UniTask

north marsh
#

No I am saying it WILL swallow

compact ingot
#
public class Test : MonoBehaviour {
    void Start () {
        try {
            Debug.Log ( "START" );
            DoTask ( 2 );
            Debug.Log ( "START AFTER DO" );
        }
        catch ( Exception e ) {
            Debug.Log ( e.Message, this );
        }
    }

    async void DoTask ( int i ) {
        await DoTaskAsync ( i );
        throw new Exception ( "DoTask EXCEPTION" );
    }

    async Task DoTaskAsync ( int i ) {
        Debug.Log ( $"TASK PRE DELAY {i} {Time.frameCount}" );
        await Task.Delay ( 100 );
        Debug.Log ( $"TASK POST DELAY {i} {Time.frameCount}" );
        throw new Exception ( "DoTaskAsync EXCEPTION" );
    }

    void Update () {
        Debug.Log ( $"UPDATE {Time.frameCount}" );
    }
}
#

the exception in async void DoTask is swallowed, the exception inside DoTaskAsync is not

north marsh
#

Why the try catch?

compact ingot
#

to show that you cannot catch it

north marsh
#

also how does UniTask help with excpetion handling in this case?

I am acutally using it, but it feels more like a better syntax sugar for me which makes a lot more thing await-able (e.g. a coroutine)

compact ingot
#

in a Team with people of different expertise regarding async it makes it much easier to write proper code

north marsh
#

Thank you ๐Ÿ™‚

north marsh
lament vine
#

Hi there, is anyone around for me to bounce a quick question off of?

#

I would really appreciate any insight you guys&girls might have, but I don't want to paste a giant script into here.

Edit: Here we go. https://hatebin.com/yusrlqlvuv

I'm working on a procedural generation script for a game i'm working on, and I'm having issues generating my roads.

thorn flintBOT
#
Posting code

๐Ÿ“ƒ 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.

quick stirrup
#

Hey guys, I need help with C# Attributes

glad badger
#

When creating complex assembly hierarchies, I usually see people nest script folders within one another as shown in the image on the left with their asmdefs kind of all over the place really because of the structuring. Is there any problem creating assembly hierarchies as shown in the image on the right?

#

I just never see people use the approach on the right and wondering does Unity have a problem with that way?

craggy spear
glad badger
devout coyote
#

Don't think there should be a rpoblem

#

Just looks weird in the editor I guess

quick stirrup
# craggy spear 1- read <https://dontasktoask.com/> 2- post your question in <#49787400440158617...

I have multiple singleton managers that serve for multiple interfaces.
For example, UpgradeManager handles some upgrade operations for "IUpgradeable"s. I am basically passing the IUpgradeable to the UpgradeManager. Upgrade method and doing the business there. I want to call the Upgrade method like an extension method for IUpgradeable but I also do not want to create static extension methods for each type of managers and interfaces that those managers serve.

I want to implement a generic solution using an attribute for these kind of methods. The attribute will get the target type from the first parameter of the method target type (for our example typeof(IUpgradeable)), then objects that inherits IUpgradeable interface will be able to call a method with same name (by probably using some Reflection) as the manager's one.

In summary, if the manager has a method like:

[MyAttribute]
DoSomething(ITargetType targetObject, int someParameter)

Then I want to be able to call like:
(myObject as ITargetType).DoSomething(5)

And it will work like as it was called like:
TheManager.instance.DoSomething(myObject , 5)

urban warren
#

So I have a hex terrain grid. Each hex cell just samples a stepped height map to get the height. My issue is, I am trying to figure out which cell the mouse is over.
My thinking was to get a ScreenToWorld raycast against a ground Plane at 0 facing up, that way I have a start and end point. Get all of the cells along the ray (from the ray origin to the point on the plane). And I thought I could just test the height of the cell vs the height of the ray at that position. But that doesn't really work intuitively, and getting the height of the ray at a point is kind of a pain.
So I was wondering if anyone had thoughts of how I could approach it differently. I guess I could make a hex mesh collider, and move it to each cell and raycast against it. But that feels really ugly to me.

sly stag
#

You should be able to get the click position at a height of 0 and then use math to figure out which hex that click would be in using only the dimensions of the hexes and your mouse x,y

#

I don't know the formula for hexes, but the same concept as if you were trying to work out the cell for a click on a grid, but obviously the formula for a hex will be a little longer

urban warren
#

Getting a cell at a position is easy if it is just a flat grid. But the height is what is messing me up

sly stag
#

Why does height come into it?

urban warren
#

Because the cells are 3D?

sly stag
#

Are you trying to align the hexes with terrain topology?

urban warren
#

No, the hexes are the terrain topology. If you look at the screenshot you can see the terrain & hexes. I am trying to figure out which one the mouse is over.

#

I have a 2D logical hex grid, and then when I generate the terrain I use a height map to give each cell a height as well.

quick stirrup
# urban warren So I have a hex terrain grid. Each hex cell just samples a stepped height map to...

I think the approach of measuring ray height you mentioned can be tried. As you said, you raycast a plane and you can stop at the first "higher than the ray" you come across by running a while loop from the nearest to the farthest one among the hexes on the horizontal path.

Additionally, I don't know if this is less costly than using a hex collider. Seems like a lot of computation as you get farther away from the hex you're aiming for.

urban warren
dusty wigeon
urban warren
dusty wigeon
#

You are over-engineering.

#

Which is not a good thing.

urban warren
dusty wigeon
#

Terrible habit.

urban warren
dusty wigeon
#

1 per hexagon.

urban warren
#

That is what I am doing right now

dusty wigeon
#

Then, why you said you dont have GO ?

urban warren
#

Because I am using GPU instancing

dusty wigeon
#

You can use GPU instancing on a material ?

#

Not exactly sure which type you are talking.

#

The Graphics command ?

urban warren
#

What? Just like Graphics.RenderMeshInstanced(renderParams, _hexPillarMesh, 0, _pillarMatrixes);

#

Though I am having trouble figuring out how to set per instance data :/

dusty wigeon
#

While having a standard renderer.

#

Also, I guess your game is gonna have a somehow isometric view or top down ?

urban warren
#

Yeah top down, like a city builder type angle

dusty wigeon
#

Yeah, even more reason to not care about performance.

#

Top down game are hyper easy to optimize.

#

Because the camera is limited to the amount of things it see.

#

Personnaly, I would use a GameObject per tile with a collider.

#

Everything would be way simpler.

urban warren
dusty wigeon
urban warren
#

Anyway, that will only work until I switch out for a generated mesh. Then I will just be using the GOs for the colliders

dusty wigeon
urban warren
dusty wigeon
#

Nothing is coming up on my search.

urban warren
dusty wigeon
#

Not exactly sure where is the issue though ?

urban warren
dusty wigeon
#

You have finite amount of mesh.

#

Which means a finite amount of instanced draw call

#

And you have a limited amount of object in view.

#

I do not think you would gain much with mesh generation in your context.

urban warren
#

Yeah I'm just not sure at what point the trade off would be. Because if it is generated, you can collapse overlapping vertices, and have fewer meshes to draw. But could no longer use instancing. And with instancing you would have to render 6x the number of meshes per hex, but you can use instancing.

dusty wigeon
#

Is your game not gonna work/take too much performance because of that ?

urban warren
#

What is "that" in this case?

dusty wigeon
#

How many draw call you expect without using any optimization ?

#

In other words, how many renderer in view you would have at a given time.

north marsh
#

any way to extend AreaEffector2D so that it could selectively affect gameobject according to my custom rule (not just based on layer?)

urban warren
dusty wigeon
#

What are you doing lol.

#

1:1 earth ?

#

You gonna need more than mesh generation to be able to sustain something like that.

#

The amount of detail you would get with 200k renderer in view would be ridiculous.

urban warren
dusty wigeon
#

Your view isnt what I'm expecting it to be

#

You said top down/isometric

urban warren
# dusty wigeon You said top down/isometric

Not sure what you would call it really? To me this is still a 'top down game'. But sorry I wasn't clearer on the angle!
You can title/rotate the camera so it looks from a lower angle or from a higher angle, and zoom in/out

sleek marsh
dusty wigeon
#

Having a fix angle make everything a LOT more easy to optimize.

urban warren
#

Not a fixed angle unfortunately

dusty wigeon
#

Everything is dynamic (Remove tiles/add tiles) ?

urban warren
#

No the terrain tiles/cells are static

#

or I guess better put, are not edited at runtime

dusty wigeon
#

So you would need to generate your mesh once ?

urban warren
#

Infinite terrain though

dusty wigeon
#

Once per chunk

urban warren
#

Yeah, it could be generated once and kept in memory

#

Though might need to dispose of them as the memory could get too large.

#

Mesh gen using burst and jobs is fast

sage radish
dusty wigeon
sage radish
#

I've seen games do mouse picking on the GPU. In fact, I believe Unity does that to know what you're clicking on in the scene (where not all meshes are guaranteed to have colliders).

#

I don't know what the go-to approach is, but a simple one would be to sample a depth texture of the scene at the mouse screen position, use that to convert to a world position and then you know exactly the world position the mouse is over.

dusty wigeon
#

It seem to me that if you intend to make such a huge terrain with the possibility of viewing everything you gonna need to integrate the notion of tessalation somewhere.

urban warren
dusty wigeon
#

I'm looking at the tiles in the back and my heart is crisping.

urban warren
dusty wigeon
#

For a standard terrain, it is kinda easy. however for something like that it is going to be a pain in the ass.

urban warren
dusty wigeon
#

I though you were doing a small top down city builder.

#

Maybe something like Civilization.

urban warren
#

The big kicker is the the cell size. Civilization's is much large so that helps a lot. I mean I might end up clamping the view down a bit so you see less.

dusty wigeon
urban warren
dusty wigeon
#

Also, the cell are gonna be really small to manipulate easily.

dusty wigeon
#

And from this angle, you would be more than fine with renderer only.

#

You have what, 400 visible renderers ?

#

If we say that every tiles is 3 draw calls, that is 1200 draw calls which run on almost every PC.

urban warren
dusty wigeon
urban warren
dusty wigeon
#

Anyway, if you have something close to what you are showing me. I feel that mesh generation is not necessary.

#

If it more in scope of what you were showing previously.

#

You gonna need to make a lot of optimization.

urban warren
#

Yeah I will have to see how instancing handles it with more instances but less geometry when I am doing the duel grid gen

sage radish
urban warren
urban warren
#

Unless I am thinking of something different than you

dusty wigeon
sage radish
# urban warren For mesh gen?

Drawing procedural meshes on the GPU has been possible for a long time. Graphics.DrawProcedural has existed since Unity 5.2.

urban warren
sleek marsh
#

i have to ask is your performance really struggling with the stuff you have going on? it seems like a scene like this should still give you 300+ frames easily

#

unless youโ€™re developing for mobile

urban warren
sage radish
#

So you're bottlenecked by the GPU.

urban warren
brisk spruce
#

aight, I think this seems like a very solid skeleton for the core of my game engine, anyone wanna give their 2 cents on it? Anything I should consider as a potential gotcha?

Game is a pseudo turn based system where everything occurs in "rounds", but the player input can queue up more than 1 "round" worth of stuff happening (IE if they click to move 3 squares, thats 3 rounds of stuff thatll happen back to back)

https://hatebin.com/tzibjqiliq

viscid blaze
#

Can anyone help with gyro?

#

So it was working and doing that before

#

but now my remote might not be working, I unplugged and re plugged and checked in project setiings and iphone is still connected

#

at the start now it changes the cube to rotate a lil but for my phone its just not showing up, I also restarted the app and nothing

#

Thats what its doing now

#

Something with the remote 5 because I reopened and now my phone isnt showing up

#

sorry

dusty wigeon
#

Good:

  • You have a separation between Input and Action which marvelous. It can look like a small things, however it really helps in the management of the flow of the game such as game state, player control, UI, etc.
  • You attempted to manage the game with the StateMachine Pattern which can really help in game that are turn base.
  • I see that you though of dividing the management of the action and the actual effect of the action.

Bad:

  • The usage of Task seem to be a bit forced and out of place. The usually pattern I see is more close to having a "current" task which is update by function call instead of a literal Task.
  • It is kinda hard to understand the purpose of RoundEvent. It may be related to the fact that you seem to have a peculiar way of doing the "rounds".
  • The StateMachine Pattern is not correctly implemented. In fact, what you have done is closer to the Command Pattern.

In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time.

Neutrals:

  • Your design of "rounds" is non-orthodox given that a single move is a full rounds worth. There is also the RoundEvent enum that is defined as a Bitmask and is pretty specific.
  • You are doing the waterfall methodology. It means that you design everything first, then you implement it all at the same time. This is not the most optimal strategy in the elaboration of any application or video game. Instead, you should opt for a methodology that build small iteration at a time. In your situation, that would be the implementation of a single Action such as move (Selection of "Unit", Highlight of available displacement, etc.). There is no need for any architecture at this stage.

https://en.wikipedia.org/wiki/State_pattern
https://en.wikipedia.org/wiki/Command_pattern

crisp zealot
#

how would I go about syncing a firing animation clip in my animator component to my weapon firerate?

dusty wigeon
crisp zealot
#
    {
        WeaponAnimator.SetBool(_Shot, true);
    }```
dusty wigeon
#

You would need to expose a parameter from the Animator directly.

#

Something like that.

crisp zealot
# dusty wigeon

here is my current parameter setup, not sure where to go with what you showed me

brisk spruce
# dusty wigeon Good: - You have a separation between Input and Action which marvelous. It can l...
  1. I am using Tasks to leverage IAsyncEnumerable and provide cascading support "downstream" in case anything lower in the tree needs to be properly async (IO ops and whatnot)

  2. Rounds can have multiple queued up, a user can click to do multiple moves of rounds (ie click 3 tiles over), but I wanna be able to short-circuit out in case partway through something interrupts the queue (their character Encounters an object of interest part way through, triggers cutscene, gets threatened by an enemy). The RoundEvent has flags for these possibilities.

  3. It will effectively be a StateMachine, the state machine parts just weren't included in the example there.

  4. I already did a bunch of proof of concepts for individual pieces of my game, starting to bring things together now and this is the first big piece. I have a solid idea of all the pieces I intend to build.

crisp zealot
dusty wigeon
dusty wigeon
#

This is a transition

#

You need to click on a state and look at the upper part*

crisp zealot
#

ah now i see

dusty wigeon
# brisk spruce 1. I am using Tasks to leverage IAsyncEnumerable and provide cascading support "...
  1. Overengineering. You can achieve whatever you are planning to do in simpler ways. Keep It Simple and Stupid (KISS).
  2. As far as I know, you do not need to have the concept at this level. You only need the concept of "interrupting". Also, the fact that it is a bitmask is strange and seem unnecessary. (I'm not asking you to explain it to me. I'm saying that the current way that you defined and named your structure (Notably the fact that it is a bitmask and that is not an Event) was not obvious for me. You take it how you want. Code should be self descriptive. )
  3. You should try to keep your StateMachine as a StateMachine and not merge it with other behavior.
  4. When I say iterative implementation, I do not say to do proof of concept, but literally build on top of previous iteration. The important is to always have something functional, take small steps to be able to rapidly come back if needed and then slowly refactor.
brisk spruce
# dusty wigeon 1. Overengineering. You can achieve whatever you are planning to do in simpler w...

Overengineering. You can achieve whatever you are planning to do in simpler ways. Keep It Simple and Stupid (KISS).
I mean, if you have an alternative Id love to hear it, but this seems actually pretty simple to me actually. IAsyncEnumerable is pretty easy to use
As far as I know, you do not need to have the concept at this level. You only need the concept of "interrupting"
Well I need to know what kind of interruption it is, I may add further metadata to it but yes, thats the big thing about IAsyncEnumerable in modern C#, for all intents and purposes it is the successor to Events. Events are pretty terrible as soon as you want them to play nice with anything async (there's a reason you pretty much never see Tasks and Events working together at the same time, you cant += Tasks together the way you expect Events to work. IAsyncEnumerable solves this.
You should try to keep your StateMachine as a StateMachine and not merge it with other behavior.
Im not. This is one of the 3-4 states of the game fundamentally (Menus, Cutscene, Ready, and Busy)
When I say iterative implementation, I do not say to do proof of concept, but literally build on top of previous iteration.
Honestly workflow wasnt something I wanted to chat about, Im familiar with waterfall, but I usually operate on much larger scales for my projects. A single sprint for me on my personal projects usually is on the scale of weeks to months, I have the time/energy for it.

#

... I should add a post to my blog demo'ing how largely speaking IAsyncEnumerable can just be a straight up replacement for Events, its largely the same principle but easier to work with, maintains stack traces better, and best of all it works with Async stuff inherently which is โค๏ธ

jolly token
brisk spruce
jolly token
brisk spruce
#

Task<RoundEvent> is to IAsyncEnumerable<RoundEvent> in the same way that RoundEvent is to IEnumerable<RoundEvent> in syncronous code

#

You can yield return and whatnot inside of IAsyncEnumerable methods

dusty wigeon
# brisk spruce > Overengineering. You can achieve whatever you are planning to do in simpler wa...

Events is actually a means of synchronisation between thread. Not sure what you mean by we never see Event and thread together. Event are not return values.
Your StateMachine contains directly the function PerformRounds which is not a responsibility of the state machine.
When I say KISS, I mean something like the following. There is no need for the usage of async process here as far as I understand the way your game works. (It might actually cause issue down the line)

private class PerformRoundsState : State {
  private Queue<Action> actions;
  
  private void Update(){
    if(actions.Count == 0)
      return;
    
    if(!actions.Peek().Update()){
      action.Dequeue();
    }
  }
}
brisk spruce
jolly token
#

I know, I'm saying that you can just return RoundEvent.Okay | RoundEvent.Interest; instead of yield return each flags because it doesn't seem like you are doing something with that.

dusty wigeon
brisk spruce
dusty wigeon
#

There is probably a more elegant way of doing this.

brisk spruce
#

Now you turned 2 things into 1, which can mess up your counts ๐Ÿ˜‰

jolly token
brisk spruce
#

Even just debugging, if Im wanting the 7th event, but the 4th and 5th event have been smooshed together by some called downstream, now my 7th is my 6th

#

but also yield return is just very nice to have overall, usually when you are Guard Clausing, yield return is slick

#

instead of

var myEvent = RoundEvent.None;
if (case)
  myEvent |= RoundEvent.Okay;
if (case)
  myEvent |= RoundEvent.Threaten;
if (case)
  myEvent |= RoundEvent.Interest;

....

return myEvent;

You get this instead

if (case)
  yield return RoundEvent.Okay;
if (case)
  yield return RoundEvent.Threaten;
if (case)
  yield return RoundEvent.Interest;

and thats it, done

#

Note how it removes your need to keep doing a "init a var, track it for the entire method, then finally return it at the very end" which gets very tiresome very quick for every single one of your implementations to be forced to do

#

Same reason why usually its a lot nicer to return an IEnumerable<T> instead of a List<T>, the latter you gotta new up a list, start filling it up, then return it at the end. Whereas the former you just yield return as you please and usually remove a few lines of code

jolly token
jolly token
brisk spruce
#

Ah you cant SelectMany IAsyncEnumerables

#

in fact normally you cant even Join em but I have a specific extension method that handles that

#

Theres a very popular mainstream library though that lotsa of folks use that lets you get all your usual Linq stuff on IAsyncEnumerables, though the methods are all async as well of course

#

I only need Join though so I have just 1 file for that, I dont need the whole lib for it

hardy sentinel
#

IAsyncEnumerable ain't that bad, why is it overengineering? it's like IEnumerable but async. Would you call usage of IEnumerable overengineering?

dusty wigeon
hardy sentinel
#

hm well right no Linq ๐Ÿ˜› but still, decent for plain iterations

dusty wigeon
#

Why would you turn something async if there is no need.

brisk spruce
hardy sentinel
#

saying assuming there's a need, of course

brisk spruce
#

as I stated earlier, I expect I have need of async there, IO operations and other such stuff

dusty wigeon
jolly token
brisk spruce
jolly token
#

Join should work like database join. I'd name it Concat

brisk spruce
#

I believe thats Intersect for Linq IIRC?

hardy sentinel
#

could complicate stuff a lot for junior devs as well

jolly token
dusty wigeon
brisk spruce
dusty wigeon
#

There is a difference.

brisk spruce
#

I dont consider it more complicated either

#

the code doesnt change, even if it wasnt async Id still have pretty much the same code

dusty wigeon
#

I'm sorry, but this is a fact. If you can remove the usage of a whole concept it only make it simpler.

#

You ask opinion, and this what I think. If you do not need that stuff, do not put it there.

brisk spruce
#

my await foreach would turn into .Aggregate() and thats.... about it

dusty wigeon
#

From my perspective, it is not needed.

brisk spruce
#

and then Id have some fewer awaits in my code, and instead of Task id return void, aside from that, itd all be the exact same logic

dusty wigeon
#

However, I'm not the one making the game, I'm just speaking from what I saw.

brisk spruce
#

I guess mostly when you talk about complicated, I view that through the lense of the actual logic.

Id be writing the exact same logic for all my code, Id just be yield returning to an IEnumerable instead of an IAsyncEnumerable

dusty wigeon
#

And it would be better.

#

You could even turn it down way more.

brisk spruce
#

because I saved... five characters?

dusty wigeon
#

No, because you removed a whole dimension.

hardy sentinel
#

sorry, I just read the script. it's quite complicated if it just intends to process a turn ๐Ÿ˜…

dusty wigeon
#

Threading can cause issue.

brisk spruce
hardy sentinel
#

best scripts are simplest scripts -- try to read it as a junior, and count the WTFs ๐Ÿ˜„

dusty wigeon
brisk spruce
dusty wigeon
#

You gonna have a lot of issue with synchronisation and undefined behavior.

tall ferry
#

i may have missed it, but what does the async actually provide in the current implementation? Is this for performance

brisk spruce
#

the actions that will occur for the turn are all pre-calced, that wont be an issue

dusty wigeon
#

How many action you intend to process ?

hardy sentinel
#

I get this, and if you intend to work alone that's totally fine! But if you intend to work with a team, might wanna consider how intuitive would be for more junior guys to process.
All depends on the context, of course. Code is code and as long as it works and won't shoot you in the foot later it's fair game and up to preference.

#

Personally some of my code is intentionally made complex and/or optimized for extensibility & performance. It's just the important high-level stuff I keep 100% clean.

brisk spruce
dusty wigeon
#

You seem to take this the wrong way.

brisk spruce
dusty wigeon
jolly token
#

Is it intended to be simultaneous? It looks half sequential ๐Ÿ˜„

brisk spruce
dusty wigeon
brisk spruce
dusty wigeon
#

However, as far, as I experienced Unity, I use rarely async.

jolly token
brisk spruce
#

Nah they all run independently of each other writing to their pipes

#

oh sorry I see what you mean, mmm yes I think you are right? but the blocker is merely:

roundEvent |= roundEvent;
which wont exactly block for a notable amount of time

#

it should definitely be pulling off the pipe way faster than the pipe is getting filled up

jolly token
#

yield stops IAsyncEnumerator til Current is consumed

brisk spruce
#

Oh you mean here?

foreach (var action in actions)
jolly token
#

Nah await foreach(var e in handler)

#

And that too probably

brisk spruce
#

so it will write to the pipe and pretty much instantly get picked up and consumed

#

I think I see what your concern is, if I do like

foreach (var enemy in enemies) {
    var roundEvent = await DoEnemyAction(enemy);
    yield return roundEvent;
}

then I will end up still only processing enemies one at a time right?

jolly token
brisk spruce
#

psuedo code but yeah the key is to fire off the events together (if you wanna get fancy it can be good to batch em too, rather than just fire em all, sometimes), and then do your yield returns after you got everything spun up and going

jolly token
brisk spruce
jolly token
#

Because val1 is not consumed

#

It's lazy evaluation

brisk spruce
#

make sure your tasks are spun up before you start yielding

jolly token
brisk spruce
jolly token
brisk spruce
jolly token
#

The main problem would be await's behavior will be different depending on where you put it (before yield or after)

#

Well Task's behavior to be specific

#

And that is very confusing

brisk spruce
#

yeah its not await that you care about, its making a new Task

#

as long as you try to avoid, as much as possible, making new Tasks after the yield, itll work very smooth

hardy sentinel
# brisk spruce I do find a lot of people struggle with Tasks and async stuff for awhile, its a ...

personally I think something like this might be quite simpler, without any performance drawbacks:

public class TurnManager {
    // ...

    public void QueueAction(TurnAction action) { .. }
    public void UnqueueAction(TurnAction action { .. }

    public void EndTurn() {
        var consumedActions = actions.Where(x => x.turnID == currentTurnID);
        onTurnEnd?.Invoke(consumedActions, onTurnStart);
        actions.RemoveRange(consumedActions);
    }
}

public class TurnProcessor {   
    public TurnProcessor() { TurnManager.instance.onTurnEnd += ProcessTurn; }

    async void ProcessTurn(IEnumerable<TurnAction> turnActions, System.Action callback) {
        // potentially filter or sort actions. e.g based on initiative etc.
        foreach (var action in turnActions) { // could even 'try to perform' them in parallel and process the results on main thread (e.g.: anims)
            if (!await action.TryPerform(out var result)) { ProcessResult(result); }
        }
        callback?.Invoke();
    }
}
jolly token
#

You can't expect everyone would understand and follow that, If it is just your personal project then well you do what you want

hardy sentinel
#

yeah, they already said it wouldn't be for the eyes of juniors, but I agree it's not great to complicate core stuff like turn processing right off the bat ๐Ÿ˜„

#

you should also take in account you'll need to process stuff like animations, position changes, and UI in main thread anyway, and as it is, everything would have to be called on main thread (including IO)

#

I personally find IAsyncEnumerable great, but it might be a bit overkill for this considering it needs boilerplate to make functional ๐Ÿ˜…

brisk spruce
#

actually since I cant see the console live, maybe it is the case, lemme retest but on my own machine to see if it actually halts and then spits all 10 out at once

#

nope no problem, the longer Task.Await doesnt block the other enumerable at all

hardy sentinel
#

it should work because linq does lazy evaluation

brisk spruce
hardy sentinel
#
        var handler = RoundHandlers
            .Select(rh => rh.Run()).Aggregate((a,b) =>  a.Join(b));

        // Process all the events and aggregate them into a single flagged enum
        await foreach(var e in handler)
            roundEvent |= roundEvent;
#

your code should work because linq does lazy evaluation, so nothing is populated or aggregated until you actually iterate on handlers (for which you use await)
but actually might have to do .Select(async rh => await rh.Run()) or smth xD

brisk spruce
hardy sentinel
#

really ๐Ÿ‘€

brisk spruce
#

its like .Max, .Min, and .Sum and etc

#

yeh, cuz it returns just a T, not an IEnumerable

#

its just a fancy .Sum function when you gotta do something fancier than just A+B

hardy sentinel
#

this might be a problem then ๐Ÿ˜› rh.Run() should be executing async code

brisk spruce
#

We are aggregating effectively a list of Tasks, not the results of the tasks

#

its uh, a sort of fancy .SelectMany for Tasks, for all intents and purposes

jolly token
brisk spruce
#

Ive tested it under some hefty loads, it doesnt seem to have much overhead, a little bit but an acceptable amount for my purposes

#

I could write a better version that actually can take multiple AsyncEnumerables, rather than repeatedly combining A+B=C, C+D=E, E+F=G, but instead just do A+B+C+D+E+F=G

jolly token
brisk spruce
#
 Busy = true;
 var roundEvent = RoundEvent.None;
 var handlers = RoundHandlers.Select(rh => rh.Run()).ToArray();
 // Aggregate all AsyncEnumerables together
 var handler = IAsyncEnumerableExtensions.Concact(handlers);

 // Process all the events and aggregate them into a single flagged enum
 await foreach (var e in handler)
     roundEvent |= roundEvent;

 return roundEvent;

Aight, now it looks a little bit cleaner :3

hardy sentinel
brisk spruce
#

Honestly maybe I should call the method .SelectMany lol, thats the closest to what it is for Linq

#

Im turning
IEnumerable<IAsyncEnumerable<T>> into IAsyncEnumerable<T> effectively

brisk spruce
#

Im surprised that VS didnt highlight the fact I wasnt using e there O_o

dusty glacier
#

can someone help me with this, I have a point (red one) on a slope and another one at the same height (blue one) how do I calculate the third point's (yellow one) position if i only know the position of red and blue dot and have the surface normal of the slope, im working in 3 dimensions

dusty wigeon
#

Oh nvm, that would give you an other point.

dusty wigeon
#

You might want to use trigonemetry here.

dusty glacier
dusty wigeon
#

Function I did the other day.

private static bool IntersectLineLine(Vector3 lineAPositionA, Vector3 lineAPositionB, Vector3 B, out Vector3 result)
    {
        Vector3 A = lineAPositionB - lineAPositionA;
        float AMagnitude = A.magnitude;
        float BMagnitude = B.magnitude;

        if (BMagnitude == 0 || AMagnitude == 0)
        {
            result = Vector3.zero;
            return false;
        }

        float dot = Vector3.Dot(A, B) / (AMagnitude * BMagnitude);

        if (dot == 0)
        {
            result = Vector3.zero;
            return false;
        }

        result = lineAPositionA + B.normalized * (AMagnitude / dot);
        return true;
    }
#

Not exactly sure of the validity, I did not use it a lot.

dusty glacier
#

I'm trying to boxcast the position for the feet ik system and the boxcast hit point is not at the same xz position as the legIK, and im trying to add or remove the needed height for it to be on the ground

dusty wigeon
dusty glacier
#

no, beacuze raycast checks a single point and there might be nothing under that point

dusty wigeon
#

You can use boxcast or sphere cast also.

dusty glacier
#

i do

#

wait a sec

#

do you see the problem, the sphere on the right is the hit position of the boxcast

#

i am aplying a correct feet height offset

dusty wigeon
#

Yeah, this is usually why you use raycast directly.

dusty glacier
#

and this happesn with raycasts

dusty wigeon
#

Not really an issue.

dusty glacier
#

?

flint sage
#

(or just do 2 raycasts)

dusty wigeon
#

I mean, you do not need to solve it at 100%.

#

You could always fall back to boxcat if raycast fail.

dusty glacier
flint sage
#

The argument of ray/boxcast is pretty useless since it won't change the fact that it's not working for them

dusty wigeon
#

I was just pointing out something. I'm not forcing anything here.

#

This is what I have done and it was working pretty well.

dusty glacier
#

raycast are just not a good option rn

#

I have been hammering at this issue for the past 2 days so I'm really clueless

dusty wigeon
#

If you use Vector3.up always you can simply take the point at the location on your vector.

dusty glacier
#

can you explain that a bit?

dusty wigeon
#

Let's say your blue dot is (X,Y,Z), then find the coordinate on the vector at (X, ?, Z)

dusty glacier
dusty wigeon
dusty glacier
#

you are right only Y is changed

#

but how do i find it

#

also take note that the slope I drew is actually a plane

dusty wigeon
#

Let's say that you have a vector that has the point (A,B,C) and the direction (X, Y, Z).
You can define the equation of the line by:
x - A = X * t
y - B = Y * t
z - C = Z * t

You can find t by using x - A = X * t or any other equation that you know the coordinate.

dusty glacier
#

I'll try this, thanks

dusty wigeon
#

You could also use trigo. (The law of sin)

dusty glacier
#

one thing, what are the lowrercase x, y, z for?

#

are they the slope normal?

dusty wigeon
#

x, y, z are the variable.

#

in the equation you have x and t as a variable.

#

It would be the position of your Vector3.up.

dusty glacier
#
Vector3 slopeNormal = hit.normal;
Vector3 HitPoint = hit.point;
Vector3 PointToProject = leg_transform.position;
dusty wigeon
dusty glacier
#

thx

dusty wigeon
#

You could also just do intersection line/line I gave you earlier.

#

Even better intersection plane line.

dusty glacier
#

im affraid that is a bit more than i can understand

dusty wigeon
#
 private static bool LinePlaneIntersection(Vector3 linePositionA, Vector3 linePositionB, Vector3 planePositionA, Vector3 planePositionB, Vector3 planePositionC, out Vector3 result)
    {
        Vector3 P01 = planePositionB - planePositionA;
        Vector3 P02 = planePositionC - planePositionA;
        Vector3 P03 = planePositionC - planePositionB;
        Vector3 IAB = linePositionB - linePositionA;
        float sqrMagnitudeIAB = IAB.sqrMagnitude;

        Vector3 normal = Vector3.Cross(P01, P02);
        float denominator = Vector3.Dot(-IAB, normal);
        if (Mathf.Abs(denominator) < 0.001f) { result = new Vector3(); return false; }

        result = linePositionA + IAB * Vector3.Dot(Vector3.Cross(P01, P02), linePositionA - planePositionA) / denominator;

        return true;
    }
dusty glacier
dusty wigeon
# dusty glacier wait that might be excatly what im looking for

You could even use directly the general equation of a plane given that you know X, and Z.

normal.x * (rigidbody.x - point.x) + normal.y * (y - point.y) + normal.z * (rigidbody.z - point.z) = 0
y = (- normal.x * (rigidbody.x - point.x) - normal.z * (rigidbody.z - point.z) - normal.y * point.y) / normal.y

dusty glacier
#

using the plane raycast still gives wrong results

#

hit is the hit information of the boxcast it is marked as a white sphere in the first image

#

'leg_transform.position' is marked as the white box

dusty wigeon
#

Why you do not directly use hitPoint ?

dusty glacier
#

it applies some movement on the x or z axis and the leg starts flying around

#

and still produces incorrect results

dusty wigeon
#

To be honest, I feel that it is what you do with the result that is wrong.

#

Can you put a gizmo where the point is ?

dusty glacier
#

which point

#

the raycast hit

dusty wigeon
#

The point you are trying to find

dusty glacier
#

one sec

#

it is the white sphere

dusty wigeon
#

So the point is correct

dusty glacier
#

see it is not in line with the leg

#

it is moved to the right

dusty wigeon
#

Or is it not align with the other one ?

dusty glacier
#

it should be right below the box

dusty wigeon
#

What is transform.leg at this heigh ?

dusty glacier
#

in line with it on global Y axis

dusty glacier
#

as soon as the angle of the plane changes from 0 the position of the leg snaps to something else

dusty wigeon
#

What is transform.leg at this height ?

#

In relation to the hitpoint.

dusty glacier
#

do you mean the distance

#

?

dusty wigeon
#

Put two gizmo

dusty glacier
#

the leg transform is the white box

#

hit point is the sphere

#

they are not in line as they should be

dusty wigeon
#

Pretty sure there is something wrong in your entry data.

#

Try it in a more isolate environment.

tired fog
#

Hi

dusty glacier
dusty glacier
tired fog
#

I want to render a mesh at local position 0, any idea why this wouldn't render it?

        var param =  new RenderParams(GrassMaterial);
        Graphics.RenderMesh(in param, GrassMeshes[0], 0,  Matrix4x4.Translate(Vector3.zero));
#

GrassMeshes[0] is just a mesh, trying to bug fix and getting to the root of the problem

#

Nvm, it was working, I just couldn't find it

wanton adder
#

Hlo guys, I am working on a top down shooter game. It's my first game that i probably will get finished. I want to figure out how do i add recoil and make a modular gun script

dusty glacier
#

thanks for the help, in the end i used the sin method

soft elm
little sluice
#

Question:
I'm creating a mesh and saving it via AssetDatabase.CreateAsset().
When i do that again and overwrite it, all existing references to that asset no longer work. (Missing mesh)
However: On a file level, it stays exactly the same. Same meta-file content, same guid, same file id. Nothing changed. I change the scriptableObject to reference the new asset and it is exactly the same as before.

Whats the correct way to overwrite Assets?

Not a bit of difference according to git. Mhhh

jolly token
#

Then SetDirty & SaveAssets

little sluice
#

Overwrite Asset, Open ScriptableObject -> Missing ( Mesh)
Overwrite Asset, Close Unity, Open Unity, Open ScriptableObject -> All good

why easy when it can be weird

jolly token
#

Donโ€™t overwrite

brisk spruce
#

does unity have a way to combine IEnumerators together simultaneously for coroutines?

#

A sort of "When All" operator

#

(not just yield returning A then B then C, as my understanding is B wont start til A finishes)

#

or something like

yield return Coroutines.WhenAll(A, B, C)

jolly token
brisk spruce
#

what do you mean by the last part? yield coroutine?

jolly token
brisk spruce
#

I see, hmm, wish there was a way to combine em into 1 easily

#

I guess I could make a simple extension method

public static IEnumerator WhenAll(params IEnumerator[] coroutines) 
{
   foreach (var coroutine in coroutines)
      yield return coroutine;
}
regal olive
#

I've got a really bad memory leak that persists even when I end play mode.

It says to account for the 21gb leak I need to use a platform specific profiler? But I don't understand what it wants / how to do what it wants

regal olive
jolly token
dusty wigeon
#

What is your platform ?

regal olive
#

Windows 11

dusty wigeon
#

Then you should use Memory Profler that are specific for Windows.

regal olive
#

You mean outside of unity or inside it? If inside it then I'm not sure how to get / use a windows specific one

dusty wigeon
#

I would guess you should look what tool there is with Visual Studio.

#

Also, you can simply guess what your issue.

#

If your game is not large.

regal olive
#

It's pretty early on right now but if the leak persists when not in play mode then it's an issue with the editor?

dusty wigeon
regal olive
#

There hasn't been a "build" yet

#

Unless you are just refering to build as the current version. It's not been built into an exe I mean

#

So from what I gather, I need to look into memory profilers in my IDE / Rider

dusty wigeon
#

Not necessary your IDE.

dusty wigeon
#

Otherwise you gonna have a lot of noise coming from the Editor.

regal olive
#

I guess it makes sesne to do that first

brisk spruce
#

the issue is you cant for sure say if you have already started the coroutine or not, I actually dislike that API

dusty wigeon
brisk spruce
#

theoretically StartCoroutine should return something distinct from an IEnumerator

#

the fact that a started coroutine and a non started one cannot really be distinguished is sort of a problem, design wise

regal olive
brisk spruce
#

if you get handed an IEnumerator, you dunno if its the coroutine itself, or the coroutine starter

dusty wigeon