#archived-code-advanced

1 messages ยท Page 104 of 1

deep jasper
#

no start, no update

sly grove
#

very little

deep jasper
#

if i have this same component on around 100objs

sly grove
#

mostly it takes up memory

deep jasper
#

well, then shouldn't be a problem

sly grove
#

but it will be a component that needs to be iterated over for GetComponent and things like that

#

its hard to quantify

#

depends on what you're doing

#

etc

deep jasper
#

i'm calling getcomponent on those 100 gameobjects only several times per minute

#

and at different circumstances

hardy jacinth
#

I keep getting the following errors when I try to perform UNDO of assignment to a serialized property with [SerializeReference]:

Could not update a managed instance value at property path 'managedReferences[2082630382636761095]', with value 'mylongpackagename.BirpShaderPreset'
UnityEditor.EditorApplication:Internal_CallGlobalEventHandler ()
#

hmm, it may be due to the prefab stage

plucky terrace
#

In Model-View-Presenter Architecture : MonoBehaviour or POCO (Plain Old Class Object) ?

half crow
#

Hi! I'm working on a steam multiplayer game.

I don't know if this issue is simple or extremely complicated. But basically, when I host a lobby in the unity engine it self or just generally launch the game (Using the space wars id: "480") everything works perfectly. After building the game however, hosting a lobby doesnt work and the steam app doesn't recognize I launched the game. But it does recognize it in the engine.

I did open steam and go to my profile before launching the game. That makes it even more confusing.

stuck plinth
stuck plinth
#

basically make sure your steam status doesn't show the game before you launch the build

half crow
#

nope doesnt work. the steam status doesnt show the game is launched

stuck plinth
#

in that case i would guess it's most likely not getting the correct app ID for your app, you should normally hardcode it in the game but try adding a steam_appid.txt file into the build folder?

half crow
#

didnt work. What do you mean by hardcode it btw?

#

Like implement the system myself?

stuck plinth
#

like set the app ID in code, where are you setting it now?

half crow
#

in the code?

#

where else do i set it

stuck plinth
#

OK, it depends on the plugin

#

there's a common older method which looks for a config file in the game folder

half crow
#

hm whats the new method?

stuck plinth
#

can you check the logs in the build then, it's likely the steam plugin is failing to initialize for some reason

stuck plinth
half crow
#

im using netcode facepunch

#

for gameobjects

half crow
#

log

stuck plinth
#

so you can see it's initializing successfully?

half crow
#

yup

stuck plinth
#

and it's still not showing up in steam?

half crow
#

yes

stuck plinth
#

then it's not initializing successfully ๐Ÿค” those messages don't look like they're coming from the steam plugin, make sure you're logging the result of that

half crow
#

where can i see the full log?

#

this is very confusing..

#

@stuck plinth

stuck plinth
#

you can turn on the player log in the build settings

half crow
stuck plinth
#

it's in the Player settings, "Use Player Log"

half crow
#

it's turned on

stuck plinth
#

then you should be able to open the player log from the console tab

half crow
#

Aight. What do I look for?

stuck plinth
#

i don't know, i don't use facepunch, errors i guess?

half crow
#

it opens in a notepad. I will give it a read.

#

Aight. So I'm getting the error: "Object reference not set to an instance of an object"

#

nothing related to steam tho. The error is from a steam manager script though

stuck plinth
#

that sounds pretty related to steam to me ๐Ÿ˜…

half crow
#

Do I send you the script?

stuck plinth
#

does the log not contain a line number?

#

make sure stack traces are turned on the player settings too if not

half crow
#

I'm not sure. I am staring into notepad. Do you see anything?

NullReferenceException: Object reference not set to an instance of an object
at Steamworks.SteamMatchmaking.CreateLobbyAsync (System.Int32 maxMembers) [0x00014] in <19bd4cc6a4004258bf538b05ac1133d6>:0
at SteamManager.HostLobby () [0x0005b] in <5deda5957ad641ba8b1b7e832b67ef7b>:0
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in <467a840a914a47078e4ae9b0b1e8779e>:0
at UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () [0x00002] in <6ef01846f2094996aa9c77a64b17827d>:0
at UnityEngine.UnitySynchronizationContext.Exec () [0x0005d] in <6ef01846f2094996aa9c77a64b17827d>:0
at UnityEngine.UnitySynchronizationContext.ExecuteTasks () [0x00014] in <6ef01846f2094996aa9c77a64b17827d>:0

#

I know where this line is in the code.

#

everything seems to be working fine in visual studio

bleak citrus
#

Make a development build.

stuck plinth
#

yeah, the easiest way is going to be attaching the debugger

bleak citrus
#

that will give you actual line numbers and file names

#

and you can also attach a debugger

half crow
#

Okay! Let me do that.

#

aha! When I host a game im getting the same error. "Object reference not set to an instance of an object"

#

seems like the error is in this line of code. @stuck plinth @bleak citrus

public async void HostLobby()
{

    await SteamMatchmaking.CreateLobbyAsync(4);

}
bleak citrus
#

it's in CreateLobbyAsync

#

there's actually nothing on that line that could throw an NRE, unless SteamMatchmakingis actually a variable (which would be weird, because it's also either a namespace or a type name)

half crow
#

Its not a variable

#

just checked

#

@bleak citrus

bleak citrus
#

right, and the problem is inside CreateLobbyAsync

half crow
#

What do i do? I'm so confused

#

it feels so easy. but i have no idea how @bleak citrus

bleak citrus
half crow
#

Yup

bleak citrus
#

So you need to look...there

half crow
#

it's one line of code. nothing wrong shows up

bleak citrus
#

so why are you looking at HostLobby?

thin mesa
#

I'd bet that steamworks isn't being initialized properly if createlobbyasync is throwing

half crow
#

because its what gets called after clickign on the button

bleak citrus
half crow
bleak citrus
bleak citrus
thin mesa
half crow
thin mesa
#

How have you confirmed it is being called

half crow
bleak citrus
half crow
# thin mesa How have you confirmed it is being called

i did a developer build. it kept giving me this error:

NullReferenceException: Object reference not set to an instance of an object
at Steamworks.SteamMatchmaking.CreateLobbyAsync (System.Int32 maxMembers) [0x0000f] in D:\a\Facepunch.Steamworks\Facepunch.Steamworks\Facepunch.Steamworks\SteamMatchmaking.cs:155
at SteamManager.HostLobby () [0x0001b] in D:\UnityGames\Beyond The Ice Wall\Assets\Scripts\SteamNetwork\SteamManager.cs:67
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in <467a840a914a47078e4ae9b0b1e8779e>:0
at UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () [0x00002] in C:\build\output\unity\unity\Runtime\Export\Scripting\UnitySynchronizationContext.cs:153
at UnityEngine.UnitySynchronizationContext.Exec () [0x0005d] in C:\build\output\unity\unity\Runtime\Export\Scripting\UnitySynchronizationContext.cs:83
at UnityEngine.UnitySynchronizationContext.ExecuteTasks () [0x00014] in C:\build\output\unity\unity\Runtime\Export\Scripting\UnitySynchronizationContext.cs:107

(Filename: D:/a/Facepunch.Steamworks/Facepunch.Steamworks/Facepunch.Steamworks/SteamMatchmaking.cs Line: 155)

thin mesa
#

This is not what I'm asking about

upbeat path
bleak citrus
#

the point is that Steam Matchmaking may not be getting initialized correctly, causing an error to be thrown when you try to create a lobby

thin mesa
#

how have you confirmed that SteamClient.Init is being called

bleak citrus
#

you need to prove that it works in the build

half crow
half crow
thin mesa
#

right. you need to actually verify that the steamclient is getting initialized

#

use logs or breakpoints

bleak citrus
#

this has nothing to do with networking, really

#

i'm asking you to prove that code runs

#

that's it

half crow
#

to make sure its running

hardy jacinth
#

breakpoints >>> debug.log

half crow
#

Ah. The code isn't being called. The log didn't go threw

#

Let me try a break point

half crow
thin mesa
#

Well there you go, that's why you're experiencing the NRE in CreateLobbyAsync

half crow
#

I don't think I have experienced this before and I've been using unity for a long ass time.

half crow
thin mesa
half crow
thin mesa
#

Ah yes the "steam manager script". That definitely tells me how and where it is being initialized since I'm super familiar with your code

half crow
#

Let me send it to you.

thin mesa
#

And where do you call SteamClient.Init

half crow
#

shit, did i actually forget it?

upbeat path
#

what? So much for 'the code works in the Editor'

half crow
upbeat path
#

I don't even see there where you call HostLoby

half crow
#

oh you mean where you call it? I call it via a button

upbeat path
#

so what is this line?
Filename: D:/a/Facepunch.Steamworks/Facepunch.Steamworks/Facepunch.Steamworks/SteamMatchmaking.cs Line: 155)

half crow
upbeat path
#

yes, and it's the line of code throwing the null ref exception.
I honestly think that someone who has used Unity for 'a long ass time' and is posting in code advanced would at least have a modicum of knowledge on how to debug

half crow
timber flame
#

I have a big problem with nav surface. When adding/removing buildings in the game, I update nav mesh surface but it considers just previous buildings not the current one even though I delay one frame and call update nav mesh method in LateUpdate!

 private void LateUpdate()
        {
            if (!_isDirty) return;
            _isDirty = false;
            UpdateNavMesh();
        }

        [Button]
        public void BuildNavMesh()
        {
            _navMeshSurface.BuildNavMesh();
        }

        [Button]
        public void UpdateNavMesh()
        {
            _navMeshSurface.UpdateNavMesh(_navMeshSurface.navMeshData);
        }

        private async void OnWorldCreated()
        {
            await UniTask.Yield();
            _worldCreated = true;
            BuildNavMesh();
        }

        private async void OnNavMeshUpdated(Structure structure)
        {
            if (!_worldCreated) return;
            await UniTask.Yield();
            _isDirty = true;
        }
upbeat path
timber flame
upbeat path
#

not what I asked

timber flame
#

When yielding three times it would be OK or wait for 1 seconds

upbeat path
#

read carefully what I asked

timber flame
#

Why is it so messy? I mean the API. I have faced this situation in UI layout as well (content size filter, change the layout size)

timber flame
#
public AsyncOperation UpdateNavMesh(NavMeshData data)
        {
            using var builderState = new NavMeshBuilderState() { };

            var sources = CollectSources(builderState);

            // Use unscaled bounds - this differs in behaviour from e.g. collider components.
            // But is similar to reflection probe - and since navmesh data has no scaling support - it is the right choice here.
            var sourcesBounds = new Bounds(m_Center, Abs(m_Size));
            if (m_CollectObjects == CollectObjects.All || m_CollectObjects == CollectObjects.Children)
            {
                sourcesBounds = CalculateWorldBounds(sources);
            }
            builderState.worldBounds = sourcesBounds;
            for (int i = 0; i < NevMeshExtensions.Count; ++i)
            {
                NevMeshExtensions[i].PostCollectSources(this, sources, builderState);
            }
            return NavMeshBuilder.UpdateNavMeshDataAsync(data, GetBuildSettings(), sources, sourcesBounds);
        }
upbeat path
#

what?

private void LateUpdate()
        {
            if (!_isDirty) return;
            _isDirty = false;
            UpdateNavMesh();
        }
        public void UpdateNavMesh()
        {
            _navMeshSurface.UpdateNavMesh(_navMeshSurface.navMeshData);
        }

is what I see in your code

timber flame
#

UpdateNavMesh();

#

:/
_navMeshSurface.UpdateNavMesh

sick flame
#

I want to use explicit fp16 flag and this is only possible with DXC, not with fxc.

agile glen
#

So fricking confused rn can anybody help

night hare
#

Can I keep plants in my game static so it doesn't change position (so no lighting change or navigation change) but rotate it a bit so it feels like there's movement?

untold moth
#

Though, I'm not sure if that's possible with static batching(assuming you're using built-in rp)

wide mulch
#

Is there a way to have polymorphic ScriptableObjects show up in this menu or something similar?

bleak citrus
#

Yeah, this works fine for me in 2023.2.20f1, at least

wide mulch
#

This is how I have it set up right now

bleak citrus
#

if I serialize a Foo, I can pick a FooChild from assets

#

and Foo is abstract (that shouldn't matter)

#

Ah

#

Remove [SerializeReference]

#

That's not meant to be used with anything deriving from UnityEngine.Object

#

You can serialize references to polymorphic Unity objects with no extra work

#

since you're really just serializing a GUID

wide mulch
bleak citrus
#

Do you have any actual instances of TestObject in your assets?

tall ferry
#

Do you have assets that actually exist as derived classes of this SO?

bleak citrus
#

I noticed you don't have a [CreateAssetMenu] attribute

bleak citrus
#

well then you won't see anything!

tall ferry
#

Is there a purpose to this class even? It looks odd

bleak citrus
#

you're serializing a reference to a specific object

#

you must have an object to refer to

wide mulch
bleak citrus
#

I'm not really following.

wide mulch
#

Do you know Minecraft data packs?

bleak citrus
#

Sure.

wide mulch
#

I'm trying to do that

bleak citrus
wide mulch
#

When RuntimeLoader is Ready(), it'll tell the RuntimeLoadedObject to either fetch already-loaded data or load the data from disk if it that specific subclass hasn't loaded yet

bleak citrus
#

you're trying to reference a type here, it sounds like

#

e.g. you want to be able to punch in TestObject into that field

wide mulch
#

Kinda, yeah

bleak citrus
#

but that field holds an instance of a RuntimeLoadedObject

#

so that doesn't really make sense

#

I'm still having trouble seeing how this would work.

wide mulch
#

I also want there to be data that's not loaded at runtime so I can create them in-editor

bleak citrus
#

If you're just looking for an identifier, you can make a single ScriptableObject class and then create one instance of it for each "thing"

#

That's sort of what I'm doing for my game's settings. Each setting is a ScriptableObject asset.

#

I have a few kinds of these assets (float setting, choice setting, toggle setting)

wide mulch
bleak citrus
#

this is still too vague for me to give a good answer for, then

wide mulch
#

I have a different idea for how I could do it

bleak citrus
#

It sounds like you want to be able to list:

  • The kind of thing you're going to spawn
  • An identifier for the thing you're going to spawn (so that a modder can target it)
wide mulch
#

I'm not "spawning" a thing, per se

bleak citrus
#

e.g. you could have a ChestLootDefinition class that knows how to parse a JSON file and generate a loot table to be used by a randomly spawned chest

#

you'd create an instance of the asset with an identifier of "tier-1-dungeon", and you'd use that asset in your dungeon scenes

wide mulch
# wide mulch I'm not "spawning" a thing, per se

There will be a type of item called a Trinket, which is purely a statistic modifier (sort of like badges from Paper Mario)
The player's inventory will have a list of all available trinkets (with duplicates), and a list of enabled trinkets.
There won't necessarily be an instance of that in the node tree, but the effects of it will need to be accessed from different places in the code

bleak citrus
wide mulch
bleak citrus
#

Each asset would represent a specific instance of something

#

a specific kind of trinket, for example

#

the identifier would be a string that uniquely identifies that kind of trinket

#

Although, this would mean that modders couldn't introduce completely new kinds of trinkets

#

because they wouldn't have a way to put more assets into your game

#

hm, this needs some more thinking

#

You can do away with these ScriptableObjects and work entirely with string identifiers -- and then keep all of your Trinket definitions in JSON files

wide mulch
#

Yeah bit I want to be able to edit the built in ones in the editor

bleak citrus
#

so when you read the JSON, you're going to deserialize it into a TrinketDefinition or something. if you make that class unity-serializable, you can store a List<TrinketDefinition> somewhere

untold moth
#

<@&502884371011731486> looks like someone is looking for a ban here

vagrant temple
#

hey, so i am using mapbox and unity together. i want to make a dragging functionality but its lagging really badly. the latitude and longitude is updating in the inspector but for some reason its taking a lot of time to update in the map - more like its not happening smoothly and is glitching/lagging
sending the code below

sly grove
vagrant temple
#

it does but it goes back and forth and becomes really laggy

#

is there a way to optimize it?

sly grove
#

Use the profiler to see what's going wrong

vagrant temple
untold moth
#

It looks like it's "other" by the color, so I'd bet on it being the editor loop.

sly grove
#

Is that other or rendering?

#

I can never distinguish

vagrant temple
untold moth
vagrant temple
#

alr one sec

#

this is what it showed when i clicked on "other" btw

untold moth
#

Also, you just disabled the other category from being shown

vagrant temple
#

alr

#

yeah

#

lemme check the doc and get back to you

#

okay so this is the hierarchy view shown at this frame

#

@untold moth

untold moth
vagrant temple
untold moth
#

Select a frame that has the lag spike

vagrant temple
#

alr

#

its like each time i drag it, it has a spike

untold moth
vagrant temple
#

hmm, more than lag, its becomes really glitchy. is it because its continuosly calling the mapbox api ?

untold moth
vagrant temple
#

i think its because its calling the api each time?

untold moth
hardy jacinth
#

I didn't work in UE, but does it compile this long even if your project is properly split Into separate compilation units?

trail quail
#

Whats the proper approach to drawing in sceneview when you're writing an overlay?

#

I want to draw lines and stuff from an overlay but it doesn't seem to play nicely with handles

thorn dome
#

Is it possible to get which slider is changing when you setup dynamic value passing in the Editor view only?
I have a audio menu script on the parent a few levels up, and would like to know there which children got changed.

sly grove
thorn dome
#

thx @sly grove, as usual. I thought so. Probably code my own delegate there

fallow dune
#

I need a little help please .
Currently using cinemachine for my camera.
When moving up and down stairs there is this stuttery jumpoing motion happening with my character. I'd like to smooth this out and hav the player move up and down the stairs smoothly without that jittery jerking motion.
My curreht method to actually get movement up stairs is as follows :

void AdjustForSlopes(ref Vector3 movementDirection)
{
    RaycastHit hit;
    Vector3 rayStart = transform.position + Vector3.up * 0.1f;
    float rayLength = characterController.height / 2f + 0.1f; // Use half character height for ray length

    if (Physics.Raycast(rayStart, Vector3.down, out hit, rayLength))
    {
        float targetHeight = hit.point.y;
        float currentHeight = transform.position.y;
        float smoothedHeight = Mathf.Lerp(currentHeight, targetHeight, Time.deltaTime * 10f);

        // Adjust movement direction to include smoothed vertical movement
        movementDirection.y = (smoothedHeight - currentHeight) / Time.deltaTime;
    }
}
sly grove
#

Otherwise use some advanced IK animation stuff

fallow dune
sly grove
fallow dune
sly grove
#

Wdym by the scale going wack

fallow dune
#

when I apply the model to the staircase mesh collider, it becomes huge and the rotation is wrong

#

They are both at origin

sly grove
# fallow dune

because your meshes are in different places and different sizes

#

Fix it in blender

fallow dune
#

I did

sly grove
#

Clearly not

#

You're also scaling the Unity objects

fallow dune
#

Using Unity Exporter

#

I'm not touching the unity scales

sly grove
# fallow dune

You can even see in this screenshot that the blue arrow for the red stairs is facing upwards

#

So the meshes are all out of wack

fallow dune
#

Super strange. In maya they are fine. Give me a sec. Thanks for the info!!

sly grove
#

Anyway fixing your meshes is going to be much easier than some complicated character controller that handles stairs

fallow dune
sly grove
#

nice

#

Honestly I would probably have just cobbled the collider together out of a few BoxColliders and called it a day

#

that looks like it can be convex though, thankfully

fallow dune
#

Ya, Now I can create simple colliders in maya. First time doing this though.

runic oriole
#

Here's a point-filtered greyscale heightmap and what I'm trying to get.

regal lava
#

more verts?

#

wave frequency seems pretty high

runic oriole
#

I've tried bumping up the resolution but the dithering persists.

regal lava
#

Looking at it a bit more, it does seem that when it does sample the height map of a greater height that the neighboring verts collapse into a lower height than what's represented on the heightmap.

fiery flame
#

I'm completely and totally at a loss, there's nothing wrong with my animator.SetTrigger or animator.SetBool, the both work outside of the code I'm using here, but when I run them in these functions they don't fire at all.

the conditionals below and the logs inside all fire as expected, except for the animator methods?????

private void TriggerAttackAnimation() {
        Debug.Log("Starting playerAnimator debugging");
        playerAnimator.SetBool("DebugBool", true);
        playerAnimator.SetTrigger("DebugTrigger");
        Debug.Log("Finishing playerAnimator debugging");

        string currentStateName = "Movement";
        if (comboStep > 1) 
        {
            currentStateName = "Attack" + (comboStep - 1);
        }

        string attackStateName = "Attack" + comboStep;
        Debug.Log("Triggering attack animation: " + attackStateName);
        if (HasState(attackStateName)) {
            // Remove existing transitions from the current state
            RemoveAllTransitions(currentStateName);
            Debug.Log("Removing Trasnisitons from " + currentStateName);

            // Create a new transition
            CreateTransition(currentStateName, attackStateName, "Attack" + comboStep);
            Debug.Log("Created Transition from " + currentStateName + " to " + attackStateName);

            // Set the trigger for the next attack
            playerAnimator.SetTrigger("Attack" + comboStep); // Use triggers to transition between attacks
            Debug.Log("Attack" + comboStep);
            Debug.Log("Set Trigger for " + "Attack" + comboStep);
            


        }
        else {
            Debug.LogError("Animator state not found: " + attackStateName);
        }
    }```

They're performed in this function below, and when TriggerAttackAnimation is called is called on top, the animator methods work, but when called below, they fail to function. I've worked on this for hours, debugged 50 different ways, all of my variables are named correctly, there aren't any syntax errors that the compiler or IDE are finding in my scripts, the animator methods are the only things not working

```c#
public void PerformComboAttack() {
        AnimatorStateInfo currentState = playerAnimator.GetCurrentAnimatorStateInfo(0);
        TriggerAttackAnimation();
        if (!currentState.IsTag("Attack")) 
        {
            isAttacking = true;
            comboStep = 1;
            //TriggerAttackAnimation();
            comboTimer = 0f;
        }
        else if (currentState.normalizedTime >= 0.9f) // Ensures the current animation is almost complete
        {
            comboStep = Mathf.Clamp(comboStep + 1, 1, 3); // Adjust the max value based on the number of combo steps
            //TriggerAttackAnimation();
            comboTimer = 0f;
        }
    }```
tough swift
#

anyone have any good tutorials on procedual generation for 2d platformer , with different room sizes?

regal lava
regal lava
#

A few ideas on how to debug this stuff is to use visual studio's debugger and step through the code, and you can watch the animator in the editor window when it's currently executing and playing those animations.

jaunty swallow
#

Is there a way to check what the main thread is stuck on? Seems to be an infinite loop that increases memory and I'm pretty sure I haven't touched anything since last run...

fresh salmon
#

Run the game with the debugger attached. When you get into the loop (when the game freezes), go back to the debugger and hit the "Break All" button to see where the execution currently is

jaunty swallow
#

pops up with source not available

#

nevermind, I've found the culprit

#

logging is mega expensive

upbeat path
fresh salmon
#

Please do not post the same question in multiple channels, stick to a single one instead

sly grove
#

Don't crosspost

brisk olive
#

my bad

#

will remove it

jaunty swallow
#

Why does terrainData.GetHeight() always return 0 despite the terrain having different heights?

#

I'm looping through every pixel in my heightmap and trying to grab the height from the terrain

lament salmon
flint sage
#

Probably because the coordinates your passing in are in the wrong space

#

Iirc it's 0..1

lament salmon
#

The input coordinates are integers so I think they are heightmap coordinates

#

Although docs dont really specify it

flint sage
#

Oh I must be thinking of some other api then

jaunty swallow
# lament salmon It shouldnt. Mind sharing your code?
for (int y = 0; y < HeightMap.height; y += jump)
{
    for (int x = 0; x < HeightMap.width; x += jump)
    {
        var pixel = HeightMap.GetPixel(x, y).r;

        var normal = new Vector3(x, _terrain.terrainData.GetHeight(x, y), y);

        if (Vector3.Dot(normal, new Vector3(x + jump, _terrain.terrainData.GetHeight(x, y), y + jump)) < 1f)
        {
            var tree = Instantiate(_treePrefab, new Vector3(x, _terrain.terrainData.GetHeight(x, y), y), Quaternion.identity, transform);

            //var data = tree.GetComponent<Tree>().data as TreeEditor.TreeData;
            //data.root.seed = UnityEngine.Random.Range(1234, 9999);
            //data.root.UpdateSeed();
        }
    }
}
#

going through debugger; x and y increase as expected but every getheight call returns 0

#

*dw I will sort out the efficiency and naming once it actually works ๐Ÿ˜…

flint wind
#

OnEnable for ScriptableObjects doesn't seem to be reliably executing, either in play mode in editor or in a built player
Is there something special about it that might cause it to not execute?
I've got 8 instances of an SO with a Debug.Log in their OnEnable, but sometimes only 1 executes, and other times it might be just 4 or 6

tall ferry
flint wind
midnight violet
inner fog
stuck plinth
bleak citrus
misty glade
#

Looking for ideas.

I have a product that I'd like to be able to do customer support for by allowing users to enter a simple-ish coupon code. I'd like the codes to be one-use-only and tied to a user ID (I'm currently using a nano id - 13 digits and reasonably easy to type: https://github.com/codeyu/nanoid-net using Nanoid.Alphabets.NoLookAlikesSafe).

My rewards are all codified in an enum, so I'm envisioning a tool that could generate a short string. Ie:

UserId: abcdefghijkl + List<RewardType> = coupon code string

where the coupon code string could get the list:

public static List<RewardType> GetReward(string userId, string couponCode) { .. ? ... }

Any thoughts? Ideally the coupon code is easily typed.

#

I suppose I could also sacrifice the List of enums and just use a single value, since that's likely to generate a coupon code that's denser/shorter

#

ie, if I tell a user "hey, enter a89m408nmav08vm4a9038gn9as834hj98jadfkasjef90w8jh90834jjoijasodfign as your coupon" they're not gonna be thrilled

#

(I can handle one-time-use abuse, but there's no way to really make it 100% bulletproof if someone can figure out the algorithm and put it on the internet, though, so maybe a little bit of security through obscurity is OK here)

#

or maybe there is..? ie, userid + secret admin key + reward = coupon; coupon + public key + userid = reward?

sage radish
#

You don't have a server that can handle this?

misty glade
#

no server architecture whatsoever

sage radish
#

Also, I don't understand what customer support has to do with coupons and rewards.

sly grove
misty glade
#

so, it's a mobile game.. imagine a guy emails in and is like "the game crashed you suck" and we can say "oops, you're right, here's a coupon ABCDEF for 100 gems" or whatever, guy is happy

sly grove
#

Something along those lines?

#

Is there anything that stops him from just reusing the same code over and over again?

misty glade
#

ya, something like that, but ideally something that he doesn't go "hey internet, enter this coupon {PraetorBlue-20points} and you'll get free points lulz"

sly grove
#

I'm not sure how this can work without some kind of centralized database or server

#

how would you stop multiple redemption

misty glade
#

I can handle that on the game client, ie, add the coupon to a hashset of used coupons or whatever

sly grove
#

I guess with the idea that if they're savvy enough to modify their local save data they can just add the gems anyway?

misty glade
#

Perhaps, but I'm less worried about that since it's stored as binary

sly grove
#

What if you do want to give them 100 gems more than once?

misty glade
#

I mean, that's possible too obviously, but less likely to be "easy"

#

oh, good call.. hm

sage radish
#

Wouldn't that just be another code?

misty glade
#

Probably would have to .. I dunno.. do something date related? Open to ideas

sly grove
#

it's getting real dicey though ๐Ÿ˜†

misty glade
#

well currently I have this existing "RewardType" enum that would be easy to use and I was hoping to use that, since there's a pretty wide variety of "reward" use cases

#

right? i thought it would be a trivial problem to solve but the more I think about it the more I am.. stumped

sage radish
#

How do you get their user ID anyway? And what is the user ID if there is no server?

sly grove
#

like realistically you could do this with JWTs. The game client can know how to decipher/authenticate the JWT and only you have the private key to sign a JWT.

But that won't give you a pretty code, it would be a base64 ugly thing

#

public key cryptography

misty glade
#

Basically the requirements are something like:

  1. Take a 13 digit userid string
  2. Generate a coupon string from #1 that codifies a list of RewardType (enums)
  3. Make it "hard" for users to generate this on their own, or share the coupon.
sly grove
misty glade
#

Yeah.. I don't know if a user is gonna be able to type a base64 string..

tall ferry
#

You could always hash it

misty glade
#

it looks like I might need to setup some lightweight webapi and have the game be able to call it or something

sly grove
#

shame, because it would be a pretty ideal solution for the rest of your requirements

misty glade
#

I'm not opposed to it.. or maybe the lightweight web api just puts the base64 encoded value online for a couple days or whatever

#

ie, "thanks for your email PB, your coupon code is 12345", you go to the app, type in your code, it goes to http://sharping/coupons/12345/pb-user-id-abcdef/ and that returns json of the base64 string, which the game parses and grants you the reward for (once)

sly grove
#

yep that could work

misty glade
#

still requires setting up the web service but... is pretty foolproof

#

coupon could come down a few days later or whatever (or maybe even immediately after the user hits it once)

#

or never, perhaps, if i wanted to do some promo or whatever

misty glade
#

visible to player in game

sly grove
misty glade
#

that playerid is already a bit long, but i could shorten it more

sly grove
#

As long as you make sure your client checks the user id and the unique id of the coupon against its internal stores

sage radish
#

Just thinking out loud, maybe isn't possible, but what if you XOR the user ID with the coupon payload? The game reverses the XOR, verifies the payload is in the correct format, maybe with some magic bits it expects in certain places.
The length of the code would be dependent on how small you can make the coupon payload.

misty glade
#

right, i could do that, but some genius will figure it out and then publicize the coupon, i'm sure

#

ie, make some webpage "cheats for sharping's game" with coupons users could generate just by typing in their userid

#

i mean, maybe it's unlikely, but.. i'd like to at least make it a little harder than trivial to break my game

#

fundamentally this is my problem ๐Ÿ™‚

sage radish
#

So you don't need any additional data except the RewardType enum?

misty glade
#

i'm open to suggestion

#

i'm reading the JWT thing pb linked

sly grove
#

yeah there's basically two ways to do that - encoding the data directly in the coupon string, or having it be a key into some external thing like your lightweight web service and getting all the details from there

#

Which we've discussed here

#

the benefit of the JWT is that only you will be able to generate them. And you can easily validate if they're authentic

misty glade
#

i'd prefer to not do the webservice if possible.. mostly just in terms of cost and tech.. game is just about ready to launch, i'd hate to have to spin up another service

sly grove
#

If someone tries to make one of their own, they will not have your key and your client can reject it

misty glade
#

game costs 0 to run currently (ie, no servers, databases, etc).. we'll eventually do teams and multiplayer and all that nonsense but i was hoping not to for now

sly grove
#

Honestly it would be pretty janky but you could host the JWTs in a public github repo and that would be free.

#

just commit new coupon codes to the repo ๐Ÿ˜†

misty glade
#

lol

sly grove
#

with the coupon code as the filename

misty glade
#

i mean, if i have to spin up a web service to host the jwts, that's.. probably fine..

#

just trying to dream up something that hits all the requirements without incurring too much cost (ideally $0)

sage radish
misty glade
#

I might honestly just do the XOR style approach

sly grove
#

KISS

misty glade
#

yeah playfab is too much infrastructure for this problem

#

(I also have partners who hate that company with a passion)

sly grove
#

Honestly anyone smart enough to reverse engineer a thing like that is smart enough to modify their gem count in your binary data anyway

misty glade
#

perhaps - the binary data is pretty resistant to that sort of thing though

sly grove
#

does it have a checksum?

misty glade
#

like I've cracked it open myself and it's ... really obscure, even knowing the exact structure

sly grove
#

I see

misty glade
#

i'm using messagepack

sage radish
#

I think most cheaters on Android are using Cheat Engine like software to change stuff in memory.

misty glade
#

I don't think it has a checksum .. you can occasionally see string data but primitives are really hard to find/see

#

yeah, i can't do much about that, and that's fine tbh

sly grove
misty glade
#

i dunno! lemme try

sly grove
#

Cheat Engine would bypass the save file entirely

#

I didn't know if it existed on Android though - but I wouldn't be surprised if it does, or another similar tool by a different name.

misty glade
#

I don't think this can parse byte[]

#

but I'm having trouble getting it into the tool from a text editor

#

vs code fails utterly at rendering byte[] in any meaningful way

sly grove
#

i don't really understand what their web form means by uint8 array going into a text field lol

misty glade
#

hm.. I think it would be pretty hard to reverse engineer this - it's packed using a custom uh.. format? ie, there's no delimiters or anything

sly grove
misty glade
#

lemme see if I can do something simliar with windows, maybe in powershell or something

sly grove
#

not sure on windows

#

yeah

sly grove
misty glade
#

oh nice, that's easier

#

i was halfway to doing it with powershell

sly grove
#

i'm sure you can in powershell but maybe not without installing some extra thing. no idea

misty glade
#
3AAbB84AAwxyjMQQZtYdAF+Ss0SbyicSJNzJdAPEEH35aTdHeuBOutUIGZ+IjH8DxBAW9HtvFRYnRbP5Z1DmnLA3A8QQoq9fn0Ouj0W6oo5Wv9+wKgPEEIgs/S92dNJMvRr3af0inXcAxBAFKQdwzW36Roz4Yu8fFX3JAMQQfm5UO3YwAUORq1mKoKlw/ADEEB1j5/1tuhdNgZSNMHSTGKwAxBC8TZWYxHRkRpTnKuFfiOjUAMQQr7X/IgQKiEGsBBk+B0DcLADEEHquS/8mNTlCgIHKKpVXFhoAxBDpvXOnDWH6Sodb8cG0JFMcAKDEED0T4yrHJ39DpAdzBoHO52+RxBBsAmH++7R1R6LXsWklcbOSBM9I3I8HRAAaooQBQgJKAzEESYQBMgIyAzIEMpACz0jcizBMcsLkAgLEEH1qUCGhzQlJib8XsjFDB9TcABTEENCAvKP7sdZPkF3S68C0fS3EEDHHtPH8MUtNojub59HYfqDEEF/etmcRuuRCpldPRomPKHvEEJuSyP+iIkJFsLzox+4bbYzEELpZV9dRjbJIg0xa5HQLUKzEEOflxP/hHmBLjZ0S7uxlrUnEEM/AVNVRQidPrLqd70jvJSzEEA3jt2QwY+9NlVDZiMuba2rEEI3xnhR7DfRNoowcFQssL0HEEAzgnAnhELJEgq8AGhcjap7EEG0Eg5csSY9MibemNDiryi/EEF5SqinBSRFAj9lMrNcifE7EEPVFwAwbACxBjQvc1CHCpM3EEBrJ8kZuXXVGvHe+Qx1Ab9/EEILESSc3WOlItGfFNvKLfmLEEGcP0QN3cnBCtAMbvQkZOOzEEEajSBVVE1NPv1cg/7YfMyXEEAPYhga4KHBHirswz52DDjnEEMzb8ZauSQ9Iiqe9FAOJq2vEEP9lfevKjQxHp/IQb/IWVHiQAYbEEF3cRYAPPPhPodHHFMt36WkBxBBftRiwiRI4R4q2Z0Y/2T7RBMQQyyhRohDeF0SXTV5ZRPl6ognEEMFh7cGrjkxFpWbvKLsmnhYAxBDpeKEvLwPdQ5Tf36FdJA1gAMQQEIoSCkTMEkSn8reWudh9jgAKloEGB5CBBpCBBpCBBgAAoJCVMs9I3I8iFBPMN5OXCAgCxBAQEMncr/1MRo6hiaxKd7bHw2IZlwoKAsQQXsk48ZsmRkqL/6x1z9g2NMMzAJcHBwHEENaLay+mCBhMovi4sjXf5e7DYg8Aw89I3It1idFdxZHEEMsoUaIQ3hdEl01eWUT5eqI=
#

you can see... some data? but it's not really decipherable

sly grove
#

ah yeah

#

nice

misty glade
#

i mean, there's a lot of data points in my save file.. i'm sure someone could tinker and find something useful to hack in millions of coins or boosts or whatever, but honestly i'm not too worried about that

#

i'm more worried that someone'll figure out XOR or rot13 the reward type with the userid = coupon code

#

I suppose I could just make it a smidge more obscure .. add some date and other checksum type stuff to the coupon, I dunno

#

ok I take it back, maybe some data is easy to read ๐Ÿ˜›

#

oh well, honestly if you can figure out how to take a random bin file in the depths of the mobile devices' OS, figure out that it's a messagepack formatted byte[], convert it to base64, edit it, then go back all the way to the bin file.. well shit, you deserve a couple extra boosts ๐Ÿ™‚

sly grove
#

it's all security by obscurity

#

and it will always be that if you store this data canonically on their hardware.

#

and that's ok

unkempt stirrup
#

preamble: this is more of an opinion/approach question than going into implementation specifics

How would you go about designing a data oriented, state driven (read: OOP statemachine) character controller? Noticeably going beyond the standard movement options, but extending this towards character unique skills.

Having at this in a more stereotypical datadriven implementation a lot of the transforms would only affect one entity (think character melee attack 1 and 2, where either 1 or 2 have some properties that cannot be generalized in a meaningful way, but are unique to a certain entity, be it player character or boss) most of the advantages (if not all) of walking data linearly are lost, but a lot of complexity is introduced to ensure character state is maintained (be it a marker component in a more ECS-y architecture, or closer ties from Systems to their data, keyvalue tables defining what state a character is inside )
On the other hand, the virtual calls are really not sexy performance wise, as the OOP state implementation would, thinking from the DOP perspective, define what systems run, in arbitrary order.

tl;dr - how to deal with entity unique behaviour in a data oriented programming style without/managaeable bookkeeping overhead

scenic forge
# sly grove public key cryptography

@misty glade You don't have to use JWT either, any public key cryptography will work.
JWT offers a standardized way to do thing that's specifically for the common use cases in web, hence it has all the bells and whistles around it like key ID, algorithm, issuer, etc, which are very unlikely not needed for your case (you can and probably will just hard code your public key and its algorithm in your game anyways)
If you are doing it this way, it will be unavoidable that the coupon will be long and cannot be manually typed, since you need to encode all the information about the coupon into it. I don't think this is an issue though. Is your game PC or mobile? If it's PC, you can just tell your player to copy and paste the code in email; if it's mobile, you can just make it a QR code and let your player scan it.

#

(And yeah the security is non existent if people really want to cheat and modify your data, just because it's binary doesn't mean people can't figure it out. Reverse engineering is way more sophisticated than "opening files and randomly guess what the bytes mean," it goes way beyond guesswork and much deeper. As always, obfuscation is not security)

dusty wigeon
frozen imp
#

@wintry ember Don't cross-post, please. Pick one channel and remove in all others you've cross-posted.

dreamy crescent
#

Hi, this might be a very specific question, if anyone knows where can I ask this tell me please ๐Ÿ™‚

I am trying to create a runtime terrain generation class, I am using the official terrain tools package from unity, they have a Heightmap class. I am trying to construct a Heightmap from a Texture2D, Texture2D class has a GetRawData() which returns a byte[] with raw texture data, exactly the same that the Heightmap constructor expects. When I try to pass this raw data to the Heightmap contructor, it fails, I am pretty sure that is because of the texture format or something like that, I don't understand texture formats quite well, could anyone point me or give an advice?

Thaanks ๐Ÿ™‚

( I know this package is not supposed to be used this way )

untold moth
#

And what api exactly are you using

sly grove
#

PNG files and WAV files are both made of bytes, they're not in the same format

bleak citrus
#

correct: this is where the type system can no longer help you (:

scenic forge
#

Depends on the language, in a language like TS where you can create branded types, eg "even though UserId and PostId are both string, they are different kinds of strings so they can't cross assign to each other (but they can still be used just like regular strings)" then type system can help you to prevent these problems.

#

(C# probably can do it with upcoming roles and extensions too, haven't looked too deep into it)

#

But practically speaking, these types of errors are pretty rare and caught very easily, so that's why it's not really a big thing to be able to track on the type level. Even in TS where it is possible, the "UserId vs PostId" scenario is really the only place I've found it to be useful.

#

I suppose if you are writing code where numbers with units are everywhere, eg some numbers are in meters while others are in miles, numbers with m/s multiplies by numbers in s should give you numbers in m, or some numbers are USD while others are Euro, then branded type could also help.

unkempt stirrup
#

I currently have a working solution for my Charactercontroller in an OOP style implementation, but this comes with all the drawbacks of such an approach

plucky terrace
#

MVVM + UniRx + Zenject + NUnit + ZeroMock (maybe)

dusty wigeon
unkempt stirrup
dreamy crescent
# untold moth Maybe explain what exactly you mean by "it fails".

Well, I am not using any API, terrain-tools package is meant to be used as an editor tool but I would like to use some features of it at runtime so I digged through the code.

(That's why I say it's a super specific question)

Heightmap is the data structure they use internally to store 'noise' data.

I have been investigating and they use some generated shaders to parse from the noise algorithm to a texture. That's really complicated to translate so it can be used at runtime so now I am trying to solve what I mentioned before.

The error I am getting is something like: "The texture width and height must to be equal".

Of course they are equal so I think the problem is the format in which the texture is encoded, I feel that depending on the format the raw data of the texture will be different, I need it as raw as possible.

Thanks for the interest btw ๐Ÿ™‚

dreamy crescent
dusty wigeon
unkempt stirrup
#

I asked you to go into answering my question precisely because I anticipated this response

#

for not gaining performance..... plain wrong. I did transition other systems from OOP to DOP and gained an easy *20-30 speedup retaining the same algorithms, with optimizations DOP allowed me, the system got a speed up x100, opening up more gameplay options due to gaining budget in the hot path

sly grove
unkempt stirrup
#

however, I am not here to discuss those things

#

but came here to get other peoples insights on their approach of implementing stateful charactercontrollers in an DOP style

dusty wigeon
unkempt stirrup
#

my friend. you're wasting both our time dragging this out

#

I'll repost the question so it does not get burried unnecessarily

How would you go about designing a data oriented, state driven (read: OOP statemachine) character controller? Noticeably going beyond the standard movement options, but extending this towards character unique skills.

Having at this in a more stereotypical datadriven implementation a lot of the transforms would only affect one entity (think character melee attack 1 and 2, where either 1 or 2 have some properties that cannot be generalized in a meaningful way, but are unique to a certain entity, be it player character or boss) most of the advantages (if not all) of walking data linearly are lost, but a lot of complexity is introduced to ensure character state is maintained (be it a marker component in a more ECS-y architecture, or closer ties from Systems to their data, keyvalue tables defining what state a character is inside )
On the other hand, the virtual calls are really not sexy performance wise, as the OOP state implementation would, thinking from the DOP perspective, define what systems run, in arbitrary order.

tl;dr - how to deal with entity unique behaviour in a data oriented programming style without/managaeable bookkeeping overhead

dreamy crescent
sage radish
#

I understand that it feels a bit icky to have a whole system and set of components that only gets used by one entity, but in terms of performance, it can't be much worse than MonoBehaviours.

unkempt stirrup
#

the main problem is inversion of ownership. In an OOP style statemachine the entity owns the system that operates transforms on it's state, by referencing a polymorphic class (accessing the correct V table as a consequence). In DOP the systems own the entities that they perform transforms on. V tables don't exist explicitly, as oprations on an entity is defined by presence (or absence) in their list of owned entities.
Depending how granular the DOP implementation becomes, each function usually associated with an OOP style abstraction/runtime polymorphic function is represented by it's own (set of) systems that own entities to perform transforms on them.

Subsequently, a typical statemachine allowing for onenter, onexit, ontrigger, ontick would be deconstructed into 4 systems, times number of possible states

dreamy crescent
tiny pewter
#

i have written some toy examples on DOP and i am less experienced than you, one thing i find out is that once the number of variables to determine the state grows then the cache locality just gone, fall back to OOP

typedef struct{
  int x,y,z...;//sizeof(State) is small
}State;//c doesnt have OOP
State states[10000];
type0 otherIrrelvantData0[10000];
type1 otherData1[10000];

then you update it as
states[i]=ChangeState(states[i]);//just copy it

but if your State is 
typedef struct{
  int variables[100];
}State;
ChangeState(states+i);//pass by pointer
```at least you can still load less data to cache, but (sizeof data needed in ChangeState)/(size of all data of one entity) finally becomes 1 if nearly all data is required to determine the state
sage radish
#

If you ignore how the switch expression is created, whether by hand or generated, and just focus on logically and performance-wise, would a big switch expression in one system be enough to solve your problem?

You would lose the ability to dynamically add different types of states that were not known at compile time. Maybe that's a requirement.

tiny pewter
#

it uses bunch of goto (i guess there is no for and while loop and switch case in asm so sharplab show this), probably a handwritten state machine will be better since it is easy to understand for human

unkempt stirrup
#

the big switch has some other downsides besides source gen (I played around with source gen for my scripting language that I attach to unity for dialogue handling) as all functions in the switch get cached, shooting the cache completely if the switch is sufficiently large, making OOP preferably again to create runtime polymorphism (this is mainly book-knowledge here, I did not test where the tipping point for big switches is yet)

#

I'll have to give it a thunk

unkempt stirrup
unkempt stirrup
tiny pewter
#

ofc there are branches inside the function, state machine is a graph and different input travelling on a different paths
if the code is large then instructions cache miss, now a function
pointer becomes a better choices...

#

but that two both require loading the instructions to cache again and the function one needs additional push stack operation?

unkempt stirrup
#

the additional push should not matter when there is a memory lookup

#

I think I'll stick to my current implementation in this case and just factor out the data more cleanly - going with function pointer to branch but keeping data linear in memory for other systems to remain quick

scenic forge
#

Maybe I'm missing something, but a character controller is only running for one entity right? So I don't think it matters if something runs a few instructions slower or having some cache misses since it's only running once per frame or whatever anyways.

unkempt stirrup
#

(also entirely random aside, nice to see a black bullet pfp)

unkempt stirrup
hardy jacinth
#

hey, is there a way to investigate what takes shader compilation process so long?

#

Before I had some shader which could recompile under ~100ms

#

now they can take even 2/3 seconds

#

and for my use case I need the compilation to be really fast

#

(working on an interactive tool for editor)

south ibex
#

Trying to figure out a way to add spatial partioning to my grass renderer.

I'm using Graphics.DrawMeshInstancedIndirect and it's a bit slow trying to draw 40000+ grass quads at once. I want to split it into cells that each render a certain amount of grass.

Issue is, I don't really know how to set this up. I've tried looking at github examples (such as https://github.com/ColinLeung-NiloCat/UnityURP-MobileDrawMeshInstancedIndirectExample) but the way I handle everything is different to how they do it so it's somewhat difficult for me to integrate their spatial partitioning method into my own code.

#

currently I just have a list that contains a struct with houses all of the data for the shader (position, rotation, scale, and some per-instance shader variables). Somehow I need to split this up into discrete cells.

regal olive
#

anyone mind helping me with inverse kinematics and procedural animation?

untold moth
misty glade
#

Is there any "magic behaviour" for particle system emission module that stops it from playing? I have a PS that's randomly stopping and I can't figure out why (I am setting emission rate over time in a tween but .. that shouldn't impact it?)

#

I'm seeing my PS isPlaying = true for exactly one frame, then it turns off

#

(and it's looping.. it should be on)

#

i'm using Emit() elsewhere

misty glade
#

Nevermind, dumb issue. Was setting emission rate elsewhere to the wrong particle system.

misty glade
#

Anyone know what this might be? Random error messages in my log:

Unable to perform online search:
  Request [GET https://packages.unity.com/-/api/search?host=editor&provider=enterprise] failed with status code [502]
UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()
blazing remnant
#

based on discord search, this happens every few weeks

misty glade
#

aight, just not really sure what it is and .. you know, we're just about to launch so not thrilled about weird/cryptic errors

#

got enough regular bugs to worry about ๐Ÿ˜‰

blazing remnant
#

It was back online a sec ago, but now it's broken again.

blazing remnant
#

still failing (not every time, but enough to break project init)

livid kraken
# south ibex Trying to figure out a way to add spatial partioning to my grass renderer. I'm ...

This answer pretty much explains how to get a cell index https://stackoverflow.com/questions/59996236/how-to-calculate-the-cell-a-point-belongs-to-on-an-infinite-grid-plane I would add that index to your data struct. Cull based on the cell bounds in a cpu job that outputs visible cells and then only render based in the matching ids. Of course things can be tremendously sped up by using a more sophisticated acceleration structure such as a octree

lone hare
#

I want to get the editor cameras position but it returns Vector3.zero unless I have opened the scene view window at least once before when entering playmode. This is the only solution I've been able to get this far but it looks horrible and I feel like there should be a easier way to do this that I'm just not aware of

    [InitializeOnLoad]
    public static class Tools
    {
        static Tools()
        {
            EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
        }

        static void OnPlayModeStateChanged(PlayModeStateChange state)
        {
            var sceneView = SceneView.lastActiveSceneView;

            if (sceneView && sceneView.camera)
            {
                switch (state)
                {
                    case PlayModeStateChange.ExitingEditMode:
                    {
                        var position = sceneView.camera.transform.position;

                        EditorPrefs.SetFloat("SpawnFromEditorCameraX", position.x);
                        EditorPrefs.SetFloat("SpawnFromEditorCameraY", position.y);
                        EditorPrefs.SetFloat("SpawnFromEditorCameraZ", position.z);
                        break;
                    }

                    case PlayModeStateChange.EnteredPlayMode:
                    {
                        var position = Vector3.zero;

                        position.x = EditorPrefs.GetFloat("SpawnFromEditorCameraX", 0f);
                        position.y = EditorPrefs.GetFloat("SpawnFromEditorCameraY", 0f);
                        position.z = EditorPrefs.GetFloat("SpawnFromEditorCameraZ", 0f);

                        sceneView.camera.transform.position = position;
                        break;
                    }
                }
            }
        }
misty glade
#

I do recall some odd stuff with editor initialize on load.. I tried something a while ago to force it to a certain scene but it didn't work consistently. What are you trying to solve by getting the editor camera position? I'm assuming some sort of custom tooling, but it seems like there's probably a better way to crack that nut

lone hare
misty glade
#

I mean, I might restructure it a bit, but if it works, it works?

#

I don't understand the unsub/sub in the constructor.. the first line'll do nothing, and the second line will sub (but never unsub, so you'll have a memory leak)

lone hare
stuck plinth
misty glade
#
        private const string HackX = "SpawnFromEditorCameraX";
        private const string HackY = "SpawnFromEditorCameraY";
        private const string HackZ = "SpawnFromEditorCameraZ";
        static void OnPlayModeStateChanged(PlayModeStateChange state)
        {
            SceneView sceneView = SceneView.lastActiveSceneView;
            if (!sceneView || !sceneView.camera) return;

            if (state == PlayModeStateChange.ExitingEditMode)
            {
                Vector3 position = sceneView.camera.transform.position;
                EditorPrefs.SetFloat(HackX, position.x);
                EditorPrefs.SetFloat(HackY, position.y);
                EditorPrefs.SetFloat(HackZ, position.z);
            }
            if (state == PlayModeStateChange.EnteredPlayMode)
            {
                sceneView.camera.transform.position = new(EditorPrefs.GetFloat(HackX), EditorPrefs.GetFloat(HackY), EditorPrefs.GetFloat(HackZ));
            }
        }

I'd write it as this, just a bit shorter, but that's just a stylistic thing rather than anything substantive

#

(keeping the keys in string constants reduces your risk of typo-bugs, which would be hard to find for this)

#

(i subscribe to the one-indent-club)

bold venture
#

quick question for Awaitable , is it needed to "dispose" of these before lets say a scene reload? Or will Unity manage the cancellations when the component is destroyed?

bold venture
#

from my research it looks like Awaitable might be a different syntax for the same Coroutines, so maybe Awaitable is managed by the lifetime of the monobehavior?

midnight violet
#

From what I read, awaitable is just a sum up async method of child async methods. As async methods do not run on another thread, I think there is nothing to dispose.

obsidian stump
misty glade
#

huh?

full ledge
#

I have an ongoing issue on my mobile app that uses firebase. when I run the app in unity, data updates just fine but when I build to iphone the arrays are replaced with empty maps.

warm stump
full ledge
warm stump
full ledge
#

should also note it's just 2 arrays, there are other arrays not being overwritten. So i have an idea but its been tough narrowing it down. it's just 2 fields of user document that its affecting, everything else is updating as expected

full ledge
warm stump
full ledge
# warm stump It may be a code issue then, but i'm taking your word that you said it works in ...

yep, tested in editor on mac and windows strenuously. I do some weird stuff with the lists so I definitely don't think it's complete voodoo. long story short the user document is a Dictionary<string, object> so to get the Lists I have to do some conversion stuff. Some of that code might work on machine but not phone

    {
        if (userObject.ContainsKey("CompletedTaskIds"))
        {
            if (userObject["CompletedTaskIds"] is List<string> completedTaskIds)
            {
                return completedTaskIds;
            }
            else if (userObject["CompletedTaskIds"] is List<object> completedTaskIdsObj)
            {
                return completedTaskIdsObj.Cast<string>().ToList();
            }
        }
        return new List<string>();
    }

    // Utility method to get UnlockedTasks as a List<string>
    public List<string> GetUnlockedTasks()
    {
        if (userObject.ContainsKey("UnlockedTasks"))
        {
            if (userObject["UnlockedTasks"] is List<string> unlockedTasks)
            {
                return unlockedTasks;
            }
            else if (userObject["UnlockedTasks"] is List<object> unlockedTasksObj)
            {
                return unlockedTasksObj.Cast<string>().ToList();
            }
        }
        return new List<string>();
    }```

essentially it reads as a List<object> but isn't
#

Might try iterating through the List<object> and add the strings individually into a List<string>

#

if .Cast is the culprit

warm stump
#

yep, tested in editor on mac and windows

soft moon
#

Please, don't cross-post. Remove this message.

mortal fern
rotund citrus
#

is there any way to run a function before awake but after scene loads?
I tried [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] but it still seems to run after all awakes.
I don't want to use script execution order.

sage radish
#

RuntimeInitializeLoadType.BeforeSceneLoad is described as:

Callback invoked when the first scene's objects are loaded into memory but before Awake has been called.

#

And the docs show an example of how you can access inactive objects in the scene before Awake has been called on them.

rotund citrus
sage radish
jaunty swallow
#

anyone familiar with the terrain's GetSteepness function?

var steepness = _terrain.terrainData.GetSteepness(x / _terrain.terrainData.size.x, y / _terrain.terrainData.size.y);

This doesn't seem to be returning the right values at all

bleak citrus
#

how did you calculate x and y?

deep jasper
#

is there a way to decimate a mesh at runtime

#

like with probuilder or smth else

jaunty swallow
bleak citrus
#

okay, so this isn't a problem with converting a world space position into a terrain-space position

#

What values are you getting out?

jaunty swallow
#

it seems to be working quite decently now, I don't know what I did

#

just messed around with the values a bunch more

serene knoll
#

I'm trying to make a collider mask using polygon colliders but when I transfer the points from local to world to local the position seems to be off. I've double checked my points and they look correct.

(The colliders should make an open space where the gap is but the space is below it)

for (int i = 0; i < _maskCollider.points.Length; i++)
            {
                drillPointsToWorldSpace[i] = transform.TransformPoint(_maskCollider.points[i]);

                Transform pos = new GameObject().transform;
                pos.position = drillPointsToWorldSpace[i];
                drillWorldTransforms[i] = pos;

                Destroy(pos.gameObject, 2);

                drillPointsToLocalSpace[i] = drillWorldTransforms[i].InverseTransformPoint(collision.transform.position);
            }

            polygonPipe.points = new Vector2[]
           {
                new Vector2(_pipeCollider.points[1].x, drillPointsToLocalSpace[2].y), // Top Left
                new Vector2(_pipeCollider.points[1].x, _pipeCollider.points[1].y), // Bottom Left
                new Vector2(_pipeCollider.points[2].x, _pipeCollider.points[2].y), // Bottom Right
                new Vector2(_pipeCollider.points[2].x, drillPointsToLocalSpace[3].y) // Top Right
           };

            _pipeCollider.points = new Vector2[]
          {
                new Vector2(_pipeCollider.points[0].x, _pipeCollider.points[0].y), // Top Left
                new Vector2(_pipeCollider.points[0].x, drillPointsToLocalSpace[1].y), // Bottom Left
                new Vector2(_pipeCollider.points[3].x, drillPointsToLocalSpace[0].y), // Bottom Right
                new Vector2(_pipeCollider.points[3].x, _pipeCollider.points[3].y) // Top Right
          };
obsidian stump
bleak citrus
#

consult the documentation

obsidian stump
bleak citrus
#

more generally, it can be used to run code as the game starts

#

I use it to load some singletons with Resources.Load

obsidian stump
bleak citrus
#

The entire game.

#

I'm not sure how you'd run code after a scene is loaded but before Awake gets called on anything

obsidian stump
#

are you sure about the entire game with plenty of scenes or just the active scene in use fen. which will get affected by this code RuntimeInitializeLoadType.

bleak citrus
#

I'm having problems with SerializationUtility.HasManagedReferencesWithMissingTypes.

I have a prefab with a MonoBehaviour attached to it that has a missing managed reference. The inspector warns me about this, and I got a warning when I originally broke the reference (by changing the namespace of a class).

However, HasManagedReferencesWithMissingTypes is returning false. I checked that my editor code is, indeed, passing this MonoBehaviour to the method.

#
foreach (var entity in entities)
{
    foreach (var component in entity.GetComponentsInChildren<MonoBehaviour>())
    {
        Debug.Log(component);
        if (SerializationUtility.HasManagedReferencesWithMissingTypes(component))
        {
            Debug.LogWarning($"{entity.name}'s {component} has broken managed references:", component);
        }
    }
}
#

The Entity component gets logged here, but no warning is printed

bleak citrus
#

ah! maybe I need to use PrefabUtility for this

#

Yep! That was it.

obsidian stump
bleak citrus
# bleak citrus Yep! That was it.

however, I don't see a way to get a list of the broken references: PrefabUtility.GetManagedReferencesWithMissingTypes doesn't exist, and SerializationUtility.GetManagedReferencesWithMissingTypes can't find anything

obsidian stump
#

i dont use much editor stuff.

obsidian stump
#

what i am thinking about this RuntimeInitializeLoadType.BeforeSceneLoad is the scene is loaded in the backend and this code runs. its like the scene is there already and its visible after running this RuntimeInitializeLoadType.BeforeSceneLoad. or the scene is not there and this code RuntimeInitializeLoadType.BeforeSceneLoad executes.

obsidian stump
bold berry
#

any profesional graphics programmers here?

drifting solstice
#

!ask

#

oh that's not a snippet

bold berry
#

just wanted to ask how to create a circilum to study graphics programming.

upbeat path
dusty wigeon
urban warren
#

Okay, so I have a chain of nodes which consist of a Vector3 position and a Quaternion rotation. The nodes always have a consistent equal spacing between them.
I have a method that takes a list of nodes, a to and from index of the nodes to modify, and a Quaternion offsetRotation.

What it does is change the position and rotation of each node in the specified index range. So that the to node ends up being rotated by offsetRotation

The way this is implemented right now is 2 nested for loops. The inner one adds a incremental rotation to each node from i to chain.Length, while the outer just loops from from to to.
(https://gdl.space/wuficunimu.cs)
The attached image illustrates what I mean about how iteratively moves the nodes up the change from i (the green ring)

This ends up being pretty slow as I have a lot of nodes and a lot of chains. Particularly the Maths.Mul as it is 2 Cross calls.

I assume there is a lot better way to do this, I am just not sure what it would be atm. Any advice?

sage radish
urban warren
#

So basically just caching it I guess.

sage radish
#

Not just straight

sage radish
#

It's a bit hard to imagine what the end result should be if you start with, for example, a chain in a S curve.

#

What if the last node just happens to already be rotated the correct orientation? What happens to the other nodes?

urban warren
#

It is an additive rotation from the from node. So if you say rotate 45, And the to node already has a rotation of 45, it will end up with a rotation of 90

sage radish
#

Oh okay, that makes sense.

#

If the data structure was all relative instead of world space, that would speed up this particular computation. But makes sampling afterwards slower.

#

Maybe it makes more sense to have the data in relative form, and also without the position, and then precompute a world space cached version of it after modifications have been made.

urban warren
#

Hmm, maybe so, that feels like it would be faster as it would get rid of the double nested for loop

#

Or... would that work...?

sage radish
#

This particular modification is even parallelize-able at the node level, because each node would be modified by the same amount, with no dependency on their parent node.

urban warren
#

So each relative-space node would just be a rotation with the root node having a position. Right?

sage radish
#

Yes.

urban warren
#

Hmm, yeah I guess so, cause then you would keep a cumulative rotation, and basically apply position + fixed distance *cumulative rotation at each node.

#

Sorry, just trying to wrap my head around it and make sure it makes sense because it is basically the 'opposite' of how it works now as the rotation is actually just calculated from the positions of the previous and next nodes.

#

And yeah I could parallelize this rotation operation you're right. It was annoying that I couldn't since it is basically just doing the same thing to each node haha.

#

Thanks @sage radish this seems like a good choice. And if I need to for some reason. I can still write methods that act on the world-space version.

sage radish
#

I always forget I can use Burst on static methods outside of Jobs.

bleak citrus
#

Yeah, definitely do that.

urban warren
#

Haha I also forget all the time you can burst static stuff. But didn't do that since the implementation felt like it had issues, and just slapping burst on it felt like just covering up 'bad' code instead of actually fixing it.

bleak citrus
#

I got a huge speedup on noise.snoise calls by doing that

urban warren
#

Yeah same haha. Its great. I just prefer to actually optimize my code properly before bursting it.

urban warren
#

This doesn't have anything to do with code. #โ›ฐ๏ธโ”ƒterrain-3d would be the appropriate channel. You can copy your message in to that channel, and then delete it from here to avoid double posting.

deep jasper
#

it's kinda related

#

since i'm currently doing some weird runtime terrain generation

#

but alr

valid flame
south ibex
#

A more complicated example could include multiple 'chains' linked together. You have the InputHandler which populates the data with the data from player input, and then something like a CutsceneHandler which overrides the data in InputHandler before whatever is requesting the data gets it.

#

small error in ChainManager.cs inside the loop in the GetState function. data should be set to the return value of chain.Value.Execute(data)

willow dome
#

Hello everyone! having this weird issue where raycasting only works when moving the target in x or z
for context:
the object selected that has the gizmos is the enemy, this moves towards the player using:

        public bool CheckView(Transform target) {
            return CheckView(target, maskObs);
        }

        public bool CheckView(Transform target, LayerMask mask) {
            Vector3 dirToTarget = target.position - Origin;
            return !Physics.Raycast(Origin, dirToTarget, dirToTarget.magnitude, mask);
        }

heres a bit more code regarding the enemy controller https://paste.md-5.net/idofawigol.cs

long ivy
#

looks like CheckAngle is wrong

willow dome
#

i took CheckAngle from an older version of this project, weirdly enough i also took CheckView.
this video is using

        private bool TargetInRange() {
            return _los.CheckRange(target) && /*_los.CheckAngle(target) &&*/ _los.CheckView(target);
        }
#

maybe this says something to you?

#

printed TargetInRange in the update and its indeed an issue with that method and not the nodes / trees

long ivy
#
  1. what is Origin and where is it set?
  2. what is the raycast hitting? Debug.DrawLine to see where it's casting
  3. have you stripped out this fsm stuff to focus on the problem?
willow dome
#

2- ill give it a try

long ivy
#

Also your raycast in CheckView is very suspicious

willow dome
#
        public bool CheckView(Transform target, LayerMask mask) {
            Vector3 dirToTarget = target.position - Origin;
            bool isClear = !Physics.Raycast(Origin, dirToTarget, dirToTarget.magnitude, mask);

            Debug.DrawLine(Origin, target.position, isClear ? Color.green : Color.red);

            return isClear;
        }

its honestly so weird

willow dome
long ivy
#

not weird, if you print what's being hit it's probably the player's collider. That's why the raycast is weird, you're checking if anything is in the way between the player and the other thing but you cast a ray that will detect one or the other 100% of the time

#

that's probably why it works if you move the collider really fast before the next physics update, but are running the TargetInRange in an Update loop

#

if you're doing a los check, you either need to filter that out or put those colliders on a different layer than the one you're using to check for collisions

willow dome
#

changing the layer seems to be working, thanks!! i have been smashing my head against the keyboard for like 3 hours with this haa_love

obsidian stump
cinder dirge
#

do u guys know how nav mesh pathfinding calculate the path after using A* for choosing rectangles ?

coral citrus
#

heya, is anyone aware of the best way to place points on a mesh uniformly (not necessarily randomly) in a compute shader?

#

i'm having some trouble

#

I'm aware of poisson disk, but in this case, there's no example of how to use that in 3D + also in compute shaders, so I've had trouble figuring it out. my current methodology is to generate X points per triangle, then in the compute shader, place them on the surface of that triangle uniformly

#

the issue is the "uniformly" bit as you can see

#

it can get somewhat close but there are some obvious artifacts around the edges of triangles

coral citrus
#

nevermind, fixed it

#

was assuming the id of the given compute shader thread was at the start of a triangle so it was connecting all kinds of incorrect things

obtuse arch
#

Need help with ImageEncoding on Job.

The logs print correctly but the saved result isnt encoded.
When I dont use jobs it works fine but doesnt when used with it.
Any idea what Im missing ?

tiny pewter
#

does unity warn you memory leak?

obtuse arch
#

nup, everything is taken care of

#

The logs,
Notice that upon job completion, the array is 22353 but when read from coroutine its back to 2.5 mb

#

Im missing something obvious at this point but unable to figure out what

tiny pewter
#

you are assigning a new native array to your job instance storage (and without dispose it the one not be disposed is resultBuff, so i wonder has unity warned you there is memory leak) but not using your own allocated buffer

obtuse arch
#

no there are no such messages

timber flame
upbeat path
deep jasper
#

how to check how close some point is to the object's bounding box

#

like Vector3.distance(SomePosition, RaycastHit.hitPoint)

#

but without a ray since there is no collider

upbeat path
#

you could use Renderer.bounds.center

deep jasper
#

well, i need to get how close the object is to one of the bounds(to the nearest bound), not to center

#

basically i want to change pixel error on a terrain object as player approaches it

#

so if player is, for example, 128 units away from the bound of terrain, pixelError should be around 50

upbeat path
#

once you have the distance to the center you can use the rest of the bounds variables to calculate the distance you want

deep jasper
#

well, how?)

#

currently my terrain is 2048x2048

#

and player can approach from anywhere

upbeat path
#

it's simple math. Look at the bounds docs and see what properties it has

deep jasper
#

not even math xD

upbeat path
#

now, don't you wish you had looked at the docs first?

deep jasper
#

I didn't know i can get bound from terraindata

#

thought it's a different thing since there is no mesh renderer

#

so i thought there is gonna be nothing in the docs, that's why i went here xD

upbeat path
#

ANYTHING which is going to showup on the gameview must have some kind of Renderer. bounds is a property of that

deep jasper
#

well, terrain doesn't have renderer

#

not even sure that my data solution is gonna work now

#

and yeah, it didnt

upbeat path
deep jasper
#

yeah but it's counting like terraindata is on 0,0,0

#

so i wrote the method which fixes that

slow jay
#

is loading images from Resources faster than from the file system?

bleak citrus
#

When you load an asset from Resources, you're reading data that was imported by the editor and stored as part of your game's asset files -- it's a Unity object, like Material or Texture2D

#

Reading a file just gives you text or bytes.

#

So if you load an image from the filesystem (say, from StreamingAssets, or from the user's Download folder), you need to do something to turn that image data into a texture

serene pawn
sacred geyser
#

For the camera component, i want a render type that is not orthographic nor perspective. I have a function to determine the screen-space coordinates of a 3d vertex. How would modify the render pipeline to implement this if at all possible?

sage radish
# sacred geyser For the camera component, i want a render type that is not orthographic nor pers...

You can create custom projection matrices and assign them to a camera. However, GPUs only support linear projections, due to how they interpolate between vertices. So, you can't create a spherical or cylindrical projection, for example.

If your function is linear, but can't be encoded as a matrix, you will have to write a custom shader to perform the projection. Everything in the scene will have to have a custom shader.

#

If your projection is non-linear, you have no option but to bypass the GPU's triangle based rasterizer completely, and write your own raytracer.

sacred geyser
#

I am praying that it is linear and will look into custom projection matrices. thank you

analog basin
#

Hello, I am learning Netcode for Entities and can't get how to rebake object to new world.
On start I have defaultWorld where everything is baked, after user connected to server I am creating 2 new worlds, client and server (it's through relay so acting like a host).
And in the default wolrd I have my enetity which I need but it's not getting baked in the 2 new world. All of them have same subscenes etc. How do I make authoring component to rebake in new worlds?

analog basin
#

Thanks

slow jay
#

In the profiler, if a function is shown as a child of another, does that mean that it was called directly from it?

The image shows an example. The function SceneSettings.Update(), there are 3 functions below it: Loading.ReadObject, Mono.JIT, Instantiate, but I don't think they are directly called from the Update?

bleak citrus
#

They can be indirectly called.

#

They also might not appear anywhere in your code at all

#

notably, Mono.JIT is counting time spent doing just-in-time compilation

#

Profiling works by measuring how much time you spend between the start and end of a marker

#

By default, there are not very many markers.

#

Deep Profile slaps a pair of markers onto every function

#

Without that enabled, you can have many layers of function calls between a parent and one of its child markers

slow jay
#

ok

#

so by default the profiler puts Profiler.BeginSample("Mono.JIT") at the start of the mono.JIT, etc?

bleak citrus
#

Something like that

#

I'm not sure that one is even a "function", per se

#

it's just marking time spent by the runtime on JIT-ing

slow jay
#

got it

violet valve
#

Hey everyone! For context, I'm working on an RTS game and need to store arbitrary collections of units. I'm trying to plan a class to hold onto a list of objects, called a UnitSet. This class should function as a wrapper for a collection and provide methods to read, write and modify the contents of the collection as speedily as possible. I'm wondering if anyone has some general thoughts that might be able to help - I haven't entirely yet decided whether the underlying collection should be an array, a hashtable, etc.

My requirements are:

  • High memory cost is allowed, memory paging is desirable.
  • Does not need to be contiguous, so null entries are okay at times.
  • Must be able to very quickly determine if an object is already in the collection (as a hashtable would), as Add(Collection) and Remove(Collection) need to act on intersecting conditions, throwing out cases where an object is already in the collection or not, as appropriate.
  • Must be able to sort frequently according to unit's selection priority (so that important units appear earlier in the collection on demand).

This class would be used pretty generically, but would be the parent to such things as control groups, so it needs to stand up to very fast changes. Also, as units die, the class would have to remove elements one-by-one through events. I'd rather not rely on Unity's null implementation at all, as units will be not be destroyed when killed per se, as part of my own batching system as well as for gameplay reasons.

I figure that the best way to achieve this is to make the UnitSet class keep track of multiple different "views" of the data, such as a dictionary to count how many of each unit type is in the collection so as to make this kind of information available without reorganizing the underlying data as often as possible.

EDIT: Whatever I do is probably going to use a lot of Span<T> for actual manipulation.

upbeat path
#

or implement your own sort and instead of the Sorted List just a List<int> or int[] where that is the ix of the original List

violet valve
#

Good thoughts - I am also considering a round-robin garbage collection routine to clean up old UnitSets. The actual unit class is BaseUnit, fyi. Thanks!

#

I'm a bit unsure whether Lists are useful at all in this case. I know I want the main collection to have a fixed size, currently thinking 512. For that reason, I think Lists are out and arrays are the only real way forward. I'm honestly caught on figuring out if and how the managed collections are optimized in the "right" way to suit my needs, and I'm leaning on thinking that they aren't, besides the default array, of course.

upbeat path
violet valve
upbeat path
#

if you have a fixed size then, yes of course use a UnitSet[] instead of a List, much better

#

you can maintain a separate count as to how many entries are in use

violet valve
#

My biggest concern, I think, is ordering and being able to determine whether an element exists in the collection. In the latter case, this is why I had considered a hashtable at all, but using the object as it's key may work, as well. I can also assign unique ids in the form of integers for units - even if they don't actually get destroyed and are instead resurrected for pooling, that id would change.

#

Probably, I don't need the objects in order in the array; just having the dictionary sorted would be alright.

upbeat path
#

not a good plan and you mentioned needing to sort frequently which is why I would have a separate sort structure indexed into the original array/list

violet valve
# upbeat path not a good plan and you mentioned needing to sort frequently which is why I woul...

As long as the class can spit out a sorted list, the data doesn't actually have to be sorted in memory, is what I mean. UI components will need to be able to populate with high priority units ahead of lower priority ones.

Here is a visual example of why this careful control over the unit set class is important:
https://youtu.be/bexWuHmV32A?t=91

It's somewhat a complex problem imo, and I really want to thank you for your insight @upbeat path.

An "over the shoulder" APM video of GSTL All-Killer StarTale_Sound! The video shows his monitor, keyboard and mouse while playing at the WCS Challenger League Qualifier!

โ–ถ Play video
#

I could also do things such as flag within the class whether the data is known to be contiguous, or if there could be a delay in spitting out neat data (dirty). It's a pretty benchmark component to the game that I'm making.

upbeat path
#

tbh, Its not complex at all, it's just a question of good data design. but at least you are asking the right questions

violet valve
#

These unit sets will also be networked so that each player in a game will have a synchronized knowledge of all UnitSets. This is both for helping synchronize AI behaviour as well as letting players show each other what units they're controlling, etc. Not all data needs to be real-time, but some should be.

upbeat path
violet valve
upbeat path
#

in that case I would not use any of the sorted collections and just maintain my own sorted array of indexes as things change, that can be implemented very efficiently and much faster than any collection

scenic forge
#

Well, if you have a public API surface designed, then you can always just use the most basic implementation first, and do a profiling to see what your actual access pattern is. Perhaps in practice it's doing less sorting than you think so that can be deprioritized, or perhaps it's the opposite and you have to prioritize sorting over everything else. It's much easier to make judgment calls with real world data, then you can just swap out the implementation without needing to change any consumer code since your public API surface is already fixed (or perhaps with these additional insight you can redesign your public API to work better with the underlying implementation)

violet valve
#

This discussion was good, nonetheless - you've largely mirrored my own thoughts. And yes, testing will be necessary throughout.

scenic forge
#

Have you profiled it prior to ripping everything away? Ideally you should have some concrete numbers on your access pattern to aid your decision making.

violet valve
violet valve
#

Good for prototyping gameplay, but nothing near a proper implementation.

scenic forge
#

That will help you know which access you need to prioritize.

upbeat path
# violet valve PC with HDRP.

Ok, I made a similar system some time ago and passed off all this kind of work to separate Threads so as not to impact the main thread. you might like to consider that although with only 512 units it should not be necessary, I was dealing with 5,000+ units

violet valve
upbeat path
violet valve
#

Thanks a ton! I think I have plenty of ideas to work with.

upbeat path
#

but now we are talkng about serious optimization, I very much doubt you will need to go that far

violet valve
# upbeat path Even better, then you can have different threads running at different priorities...

More likely, whatever directly affects the local player is high-priority - especially if they paged certain control groups before others. Scenario-related sets or anything that gets produced as a result of an AI eyeing the battlefield can be low priority - I want to make sure that the player's control is unhindered. Whether a unit is in view or not actually doesn't matter as it is essentially foregrounded if it's referenced in a group that is high priority at all.

upbeat path
#

Souinds to me like you are on the exact right path, best of luck with your implementation

upbeat path
violet valve
upbeat path
#

there is no better feeling than when a plan comes together and it 'just works'

coral citrus
#

heya, anyone experienced with compute shaders that could help me out?

I've written a compute shader that takes the vertices & triangle indexes of a given mesh. the shader's x thread id corresponds to the triangle # (in this case, there's only 1), then the y and z ids are used to place them on the triangle

I'm getting really strange results though. f.ex, with only three vertices, even though they log as (1.5,1.5), (1.5,0.0), and (-1.5,1.5), occasionally the (1.5,1.5) vertex will appear in the shader to be positioned at (-1.5,-1.5) instead. just weird stuff like that- if I reenable the component (and restart the shader), it will then appear normal again

#

I'm pretty new to using compute shaders so I'm sure I'm doing something wrong here

deep jasper
#

hi guys

#

i have a value which i want to operate with each frame

#
int val = 5; // goes from 5 to 100
int thing = 1000; // goes from 850 to 1700
int botBound = 850;
int topBound = 1700;

val = some kind of lerp(850, 1700, 5, 100);
#

i want the value to be 100 when thing is 1700

#

and 5 when thing is 850

#

if lower than 850, then it's still 5, if higher than topBound, then it's still 100

tall ferry
deep jasper
#

oh shit

#

wrong channel

sage radish
deep jasper
#

isn't that some kind of task which Lerp can handle

#

in a single line of code

#

(i don't know how lerp works cuz never used it)

coral citrus
#
[numthreads(8, 8, 1)]
void InitializeGrassChunk(uint3 id : SV_DispatchThreadID)
{
    GrassData grass;
    int adjId = id.x * 3;
    float offset = id.x % _GrassPerTriangle;
    
    float3 v1Pos = _PlacementVertexBuffer[_PlacementTriangleBuffer[adjId + 0]] * _Scale;
    float3 v2Pos = _PlacementVertexBuffer[_PlacementTriangleBuffer[adjId + 1]] * _Scale;
    float3 v3Pos = _PlacementVertexBuffer[_PlacementTriangleBuffer[adjId + 2]] * _Scale;
    
    float noiseX = abs(snoise(float3(id.x, id.y, 0.0f) * 1000.f)) * 1.25;
    float noiseY = abs(snoise(float3(id.y, id.x, 0.0f) * 1000.f)) * 1.25;
    float a = (id.y % _GrassPerTriangle) / _GrassPerTriangle;
    float b = (id.z % _GrassPerTriangle) / _GrassPerTriangle;
    if (a + b >= 1)
    {
        a = 1. - a;
        b = 1. - b;
    }
    
    float3 a1 = (1 - sqrt(a)) * v1Pos;
    float3 a2 = (sqrt(a) * (1 - b)) * v2Pos;
    float3 a3 = (sqrt(a) * b) * v3Pos;
    
    float4 pos = float4(v1Pos + (a * (v2Pos - v1Pos)) + (b * (v3Pos - v1Pos)), 1);
#

this is my code atm

tall ferry
# deep jasper isn't that some kind of task which Lerp can handle

you can use lerp for the remap sure, you still need to also clamp thing to the lower and upper bound. Then do your logic to remap a range of (850 to 1700) to (5 to 100). Lerp is just a simple equation
https://docs.unity3d.com/ScriptReference/Mathf.Lerp.html
Also no need to worry about making this a single line of code already, you dont even have the logic down yet.
Actually for lerp, you would also need to inverse lerp to find how far your value is between 850 to 1700 in terms of a percent. Then lerp would use that percent to get the value from 5 to 100

coral citrus
#

is it incorrect then to think of "id" as a vector3 constrained to the threadgroups I used in .Dispatch?
initializeGrassShader.Dispatch(0, grassPlacementMesh.mesh.triangles.Length / 3, grassDensity, grassDensity);

wet sail
#

can someone please tell me the bind-pose of a bone of a skinned mesh, its relative to what? is it the world matrix or some matrix relative to root node or what?

sage radish
coral citrus
#

ahhhhhh

#

that's what I was missing

sage radish
#

But since it's an integer division, any fractional part will be removed, so you'll want to divide by float and use Mathf.CeilToInt. This means you might get extra threads invoked, so you have to add a range check at the start of your compute shader kernel and early exit if it's an extra ID you don't want.

coral citrus
#

got it, that makes sense

#

I'll use multiples of 8 for now while testing and do that once I've confirmed the triangle plotting behavior isn't buggy

#

yep, that fixed it

#

awesome

deep jasper
#

can i blend this with the "skybox color"

unkempt stirrup
# violet valve Hey everyone! For context, I'm working on an RTS game and need to store arbitra...

this sounds like some general purpose database to me instead of something you do from scratch - you can bring in sql or some other database that fits your usecase. supporting rw and sort throws out most naive implementations I've used in my own solutions so far (they had a set number of entities with no sorting required)

depending on the number of entities you can use a sparse array for your entities saving indices into a packed data array. that way checking for an entity present becomes sparseArray[entityId] != -1 (basically a hashset performance wise) and retrieving a value becomes valueArray[sparseArray[EntityID]] (more or less same perf as List<T> due to double dereferencing) but this really eats memory, especially if you want to use normalized tables and have many sparse arrays - on non normalized tables you may up using a lot of null entries in the value arrays.

Sorting would obv touch both arrays, adding is easy (add a new value to the value array, put the index in the sparse array) deleting is trickier if you want to recompact the value array (shifting values down + shifting indexes in the sparse array) but possible to make performant if you use a mark dirty / mark for deletion approach and clear things out over time

soft panther
#

Hello idk if this is advanced but I have a problem with my WebGL build for my unity game. I am making a 2D platformer and i used Tilemap Collider 2D and it works perfectly in the editor but when i make the webGL build and post it on itch my player juste goes through the floor and my collisions don't work and idk what to do

untold moth
soft panther
#

yep if i do the build and run function i have the same problem

untold moth
soft panther
#

Here's the code but i don't understand why the problem would be in the script if in the editor it works but just not in WebGL

untold moth
thorn flintBOT
untold moth
soft panther
#

in fixed Update

untold moth
#

And a video of it working correctly

coral citrus
#

i've fixed up the actual plotting algorithm but I'm still having some trouble that I suspect might be with how I'm handling the ids
the attached picture is proof the plotting is working (points at 0,0 and 0.0625*8,0 respectively)

#

but this is what I get with ```
float s1 = id.y / _GrassPerTriangle;
float s2 = id.z / _GrassPerTriangle;

#

_GrassPerTriangle is 16, and id.y and id.z range from 0 - 16, so it seems logical to me that they should always be a spread of values, and yet they seem to be very consistently incorrect

#

this is with [numthreads(1, 8, 8)] and initializeGrassShader.Dispatch(0, grassPlacementMesh.mesh.triangles.Length / 3, grassDensity / 8, grassDensity / 8);

#

even setting id.y and id.z to a 1-16 number gets correct results which makes this even more confusing

long ivy
#

are you sure you don't need a cast there? I would assume s1 and s2 are always 0f

#

well except in the case of 16, assuming you aren't modding id.y and .z by _GrassPerTriangle like you did in your above snippet

coral citrus
#

yeah, I've tried it by creating a float fId = float3(id.xyz) and using that, but same deal

#

I've actually managed to get it to kind of work but I'm realizing the way I'm getting the point values isn't going to work

#

this is with initializeGrassShader.Dispatch(0, grassPlacementMesh.mesh.triangles.Length / 3, grassDensity, 1);

#

which is actually perfect. it even works if I up the thread count, so this is ideal

#

as soon as I change the 1 back to grassDensity however

#

I get this... which is mapping points correctly, but using just ```
float s1 = id.y / _GrassPerTriangle;
float s2 = id.z / _GrassPerTriangle;

for points is clearly not going to fill the triangle in the way I was hoping, since it's seemingly random every time I restart the shader
#

I assume it's because of the semi random order the threads are executed, so I need to probably use the sum of id.y and id.z instead..? but I have no clue how I'd map that single value to two separate values

#

another random incorrect variant, which is, again, not that far off, but still not a uniform plotting by any means

soft panther
vapid hatch
#

Hey guys , i'm trying to write a script to set UV2 of imported meshes. I would like to use my own uv channels for lightmaps but unity keeps using its own uv's ignoring those imported. Can someone help me to write a code for that ?

wet sail
#

im sooo confused about quaternions: why do these two arent equivalent ????
var kfr_delta = Quaternion.Inverse(ToWorld(a)) * ToWorld(b);
var kfr_delta = ToWorld(Quaternion.Inverse(a) * b);

sly grove
#

The order in which you perform operations matters

wet sail
#

ah yeah. makes sense.

#

how do i know which order to apply ?

#

how do i decide which one is the valid one ?

upbeat path
#

If in doubt, break the statements down into single steps and Debug.Log them

wet sail
#

completely useless with quaternions, not intuitive at all

#

even if i debug them what am i gonna do?

#

so my problem is

#

gA, gB, gParent = gameobjects (gA,gB are childs of gParent)
a and b = localRotations of a & b
c = rotation of parent
how do i calculate the "difference" of the b-a rotation then put it into world?

im not sure which order is valid

upbeat path
#

that does not matter. Only the start point(s) and end point are important. what you can see, with experience, is the changes each stage appliies

bleak citrus
#

I do this in a component that attaches Unity Spline knots to transforms

#

although I just noticed that I named these things backwards

#
var knotWorldRotation = splineTransform.rotation * knot.Rotation;
var toParentRotation = Quaternion.Inverse(parent.transform.rotation) * knotWorldRotation;
rotationOffsets.Add(toParentRotation);
#

That should really be toKnotRotation

#

(and that's how I use it)

#

Quaternion multiplication is not commutative, but it IS associative

#

(that's not relevant here, though)

wet sail
#

so u are saying Inverse(ToWorld(a)) * ToWorld(b); ?

bleak citrus
#

(a * b) * c = a * (b * c)

bleak citrus
#

You can read this as:

  • inverse the rotation of a
  • apply the rotation of b
#

This is exactly like finding a vector between two points

#

(b - a)

#

Your rotation is now inv(a) * b, so a * inv(a) * b = b

#

Order is important.

#

If you multiply this on the left hand side of your starting rotation (a), you get

#

inv(a) * b * a

#

and i have no idea what that produces

bleak citrus
wet sail
#

yep thats what i did, the thing is that the animation retargeting isn't still correct. tbh im not sure anymore. look this gif

im basically doing that by using inverse(parentOfAandB.rotation * a.localRotation) * (parentOfAandB.rotation * b.localRotation)

bleak citrus
bleak citrus
#

like, a cube with two cube parented to it

#

you want to eliminate as many variables as possible

bleak citrus
wet sail
#

alright but that's a hassle as i have to rig and animate a cube

bleak citrus
#

eschew everything else: just write code that computes a rotation between two transforms

bleak citrus
bleak citrus
#

If you want to calculate a rotation between a and b in the parent's local space, you shouldn't be using the parent's world rotation at all

#

Perhaps that's your problem

#

although, since you're applying the same rotation to both a and b, that shouldn't change the resulting delta-rotation

wet sail
bleak citrus
#

I would do some sanity checking by just calculating a fixed rotation with Quaternion.AngleAxis or something

#

to make sure that applying the same rotation to different armatures works the way you expect

coral citrus
#

it seems like I'm getting consistent values for id.y, but not id.z, or not when used together, despite it seeming like that should be the case

coral citrus
#

my bad, I searched up compute shaders and saw people talking about them in here so I thought it was OK

urban beacon
#

Hey guys, so I'm trying to optimize a voxel engine, which currently takes way too long to load a world. The biggest bottleneck is the loading of the texture atlas, which takes over 6 seconds. Specifically, it's the operation Texture2D.LoadImage(). I was attempting to make this an asynchronous operation, but Texture2D.LoadImage() is not an operation that can be done on a thread apparently. Unity restricts it to the main thread. As such, I don't see a way to feasibly do this operation asynchronously. Similarly, I tried to do it in a coroutine, but the coroutine isn't true multithreading so it'll execute the entire LoadImage() function before any yield returns can be called, so the end result is that its still frozen for 6+ seconds. Is there any way to get the LoadImage() function to run asynchronously in the background, without impeding the main thread?

urban beacon
# sly grove You can load an image asynchronously lwith this https://stackoverflow.com/a/6914...

I've turned

        // string atlasPath = Path.Combine(Application.persistentDataPath, "Maps", PersistentDataManager.Instance.Map, "Atlas", "UVChecker.png");

        if (!File.Exists(atlasPath)) {
            Debug.LogError("Texture atlas file not found at " + atlasPath);
            return;
        }


        byte[] fileData = File.ReadAllBytes(atlasPath);
        Texture2D atlasTexture = new Texture2D(2, 2);
        
        if (!atlasTexture.LoadImage(fileData))
        {
            Debug.LogError("Failed to load texture atlas from file data.");
        }

        atlasTexture.wrapMode = TextureWrapMode.Clamp;
        atlasTexture.filterMode = FilterMode.Point;
        atlasTexture.mipMapBias = 0f;

        material = new Material(Shader.Find("Standard"));
        material.mainTexture = atlasTexture;```
into 
```private IEnumerator LoadTextureAtlas()
{
    string atlasPath = Path.Combine(Application.persistentDataPath, "Maps", PersistentDataManager.Instance.Map, "Atlas", "Packed_Atlas.png");
    string uriPath = "file://" + atlasPath;

    using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(uriPath))
    {
        yield return uwr.SendWebRequest();

        if (uwr.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError($"Failed to load texture atlas: {uwr.error}");
        }
        else
        {
            Texture2D atlasTexture = DownloadHandlerTexture.GetContent(uwr);
            atlasTexture.wrapMode = TextureWrapMode.Clamp;
            atlasTexture.filterMode = FilterMode.Point;
            atlasTexture.mipMapBias = 0f;

            material = new Material(Shader.Find("Standard"));
            material.mainTexture = atlasTexture;
        }
    }
}```
#

However, it still lags and freezes for a good moment

#

my guess is that downloading the texture takes a shit load of time

#

specifically because the atlas in question is a massive 16k x 16k image

violet valve
distant fable
#

Hi friends, I have one script that converts all game objects with a MeshFilter into the 3D model (.fbx), but this script converts all the MeshFilter into separate meshes for example if 5 Meshfilter have the same mesh then these scripts generate 5 separate mesh into generated 3d model. Please help me to optimize this script. Thanks https://hastebin.com/share/gaduyahaxu.swift

sly grove
south ibex
#

What would be the best way to handle spatial partioning for instanced objects without too much overhead?

dusty wigeon
viral igloo
#

Hey guys, i'm trying to figure out how to use IAP without using Unity's Game Services :) I would appreciate if someone could point me in the right direction!

inner fog
south ibex
#

Each of those tiles will contain a list of the data to pass to Graphics.DrawMeshInstancedIndirect, right? Wouldn't I need to either merge all tiles within view into one list before passing or have multiple calls to DrawMeshInstancedIndirect?

unkempt stirrup
scenic forge
#

I highly doubt an in memory database is the way to go if you are looking for performance. In general, specialized solutions are going to be more performant than generalized solutions, and databases are very generalized. On top of that, there are lots of features databases implement (eg ACID transaction) that are overheads but irrelevant to the problem.

unkempt stirrup
#

especially if you want to maintain data coherence over time so performance does not degrade due to data fragmentation, further complicating implentation of the specialized solution

scenic forge
#

That's fair, and is why the first thing I suggested for them to look at is their access pattern. Eg if insertions and deletions access far outweighs sorted lookup access, they can only sort on lookup rather than on insert/delete.

#

Without knowing their specific access pattern, there's no other solution than a generalized one. And a generalized one as you said, is difficult to implement and maintain.

unkempt stirrup
#

๐Ÿ‘

acoustic vortex
#

i wanna do something complex but i don't know if it will work, a script that checks if any headset or headphones are plugged in/connected on the pc, and if one is detected, it activates a headset (as a gameobject) on the player

tired fog
#

Hello, im trying to use Graphcs.RenderMeshIndirect but I got into two issues.
1- When i set a camera in the RenderParams struct, the rendering starts to flickers. I need to set a camera to accuretly perform Frustrum Culling, both in scene and game view, but it starts to flicker on an off outside play mode. Im launching the rendermeshindirect in late update.
2- Im setting the ViewPort matrix for frustrum culling, but it seems to be losing the position of the camera? Not sure why but it's acting as if the camera was always at 0,0,0 but the rotation is correct.

pastel wedge
#

NativeArray currently doesn't support ref return but it does provide NativeArray.AsSpan
so if I'm doing something like this:

var array = new NativeArray<float2>(new[]
{
    new float2(0, 0),
    new float2(0, 0),
    new float2(0, 0)
}, Allocator.Temp);

var span = array.AsSpan();
span[2].x = 10f; // now array[2] is float2(10, 0)

am I doing something illegal, are there any pitfalls with this approach. is this just bypasses safety checks or something worse?
for atomic types it's obviously not that critical but for big struct can be useful

tall ferry
acoustic vortex
#

Well some friends suggested me Naudio but i dont know how to get it, Because of i understood Naudio act like a audio manager or somethin

tall ferry
acoustic vortex
#

Yeah..well maybe a script that detect the current audio port and if it detects a new one, it activate the gameobject?

deep jasper
#

hi guys

#

i have this code for combining splatmaps

void CombineSplatmaps(TerrainData mergedTerrainData)
{
    ISet<TerrainLayer> layers = new HashSet<TerrainLayer>();
    foreach (TerrainLayer layer in data.terrainLayers)
    {
        layers.Add(layer);
    }

    mergedTerrainData.terrainLayers = layers.ToArray();

    int resolutionFactor = 8; // 8x8 formation
    int cellResolution = 512;
    int targetResolution = 4096;

    float[,,] cellData = data.GetAlphamaps(0, 0, cellResolution, cellResolution);
    float[,,] splatmapData = new float[targetResolution, targetResolution, mergedTerrainData.terrainLayers.Length];

    for (int y = 0; y < targetResolution; y++)
    {
        for (int x = 0; x < targetResolution; x++)
        {
            int sourceX = x / (targetResolution / (resolutionFactor * cellResolution));
            int sourceY = y / (targetResolution / (resolutionFactor * cellResolution));

            for (int layer = 0; layer < mergedTerrainData.terrainLayers.Length; layer++)
            {
                // Transfer and blend the splatmap data from the original terrain to the merged terrain
                splatmapData[y, x, layer] = cellData[sourceY % cellResolution, sourceX % cellResolution, layer];
            }
        }
    }

    mergedTerrainData.SetAlphamaps(0, 0, splatmapData);
}```
#

and well, the problem is, for each individual terrain i need to build 4096x4096 heightmaps from 512x512 pieces

#

which is 16ย 777ย 216 writes to the splatmap array, and the same amount of reads ig

#

is there a way to use these 512x512 pieces but combine them so resulting heightmap is 1024 for example

#

like a downscaled version

#

i kinda need to do that at runtime, so i can definitely go for the compute shader

#

my goal is to show a 256x256 heightmap when terrain objects is reeeeally far, and show 4k when player is standing close to the terrain(around 100 units from the corner)

sly grove
deep jasper
#

Well, the problem is

#

I have 144 terrains for the entire world

#

And if i keep all of them with splatmap of 4k, i will never have enough RAM/VRAM to store all this data

#

I ofc can parallel the calculation thing and even move the computations to the GPU, but i need to somehow transfer 8x8 grid of 512x512 alphamaps into a single 2048/1024/512 map(with quality loss of course)

#

And idk how to achieve the quality loss

untold moth
#

How many terrains do you expect to be rendered at once?

#

In full resolution

deep jasper
#

Not more than 4 ig

#

in 4k

untold moth
#

Then maybe it's a job for streaming? You only load 4 of the terrains from the disk at once and unload them once they're far enough.

deep jasper
#

I don't want to unload them, because i want to keep distant terrains visible but low quality

sly grove
untold moth
sly grove
#

Or rather bicubic interpolation

#

I accidentally words

deep jasper
deep jasper
#

And also i dynamically set the pixel error and use distant fog to hide small geometry updates

untold moth
#

The point is loading/unloading from disk to save on the used memory.

deep jasper
deep jasper
#

And you can avoid disk loading operations this way

#

And well, in case you are high in the sky, most of terrains can stay on 512 splatmap, which means they won't eat a lot

untold moth
deep jasper
untold moth
deep jasper
#

It won't if you don't let it

#

Well, as i think about it, i need to keep the 64 small pieces with 512x512 alphamap 144 times...

#

Which means a lot of memory wasted anyways

#

More than my pc has probably

#

My calculations brought me to 72 gigs xd

jaunty swallow
#

Trying to instantiate some foliage procedurally, I can't get the rotations right.

var normal = _terrain.terrainData.GetInterpolatedNormal((x + halfSize) / _terrain.terrainData.size.x, (y + halfSize) / _terrain.terrainData.size.y);

//grass.transform.rotation = Quaternion.Euler(0, UnityEngine.Random.Range(0f, 360f), 0);

var target = normal - grass.transform.position;

grass.transform.rotation = Quaternion.LookRotation(target, grass.transform.up);

Their rotations seem to vary a little bit but are within a very close range
Any ideas?

worthy citrus
#

Hi. Does anyone have any experience trying to use code generation through Cecil when deploying for IOS? I want to modify all properties with [Notify] attributes and add some code to the setter method to invoke property change events. I've been able to do this for Windows by using IPostprocessBuildWithReport and simply modify the assembly post build. But how can I intercept that when building for IOS so that I modify the assembly before it's converted into Xcode project?

SOLUTION: I found out that you can use "IPostBuildPlayerScriptDLLs" to intercept the assemblies before making xcode project.

bold venture
#

I've been working on implementing scene streaming (additive scenes) and combining that with a save/loading feature. One of the parts of the implementation is a ScriptableObject that is a map between a key (string) and a Prefab (located in the Assets folder, not the scene). When i load a savegame it works in the editor, but I just found out by debugging that in the player build i can not Instantiate(prefabMap.value) due to the reference to the Asset Prefab being the string "null". To load my game i load a single scene "Loading" and then reload the active scene. I'm guessing that the ScriptableObject values gets garbage collected and lose the reference?

I've looked at the Addressable package and it looks like it might be able to solve this, however, I would really like to keep the scope of my project as limited as possible. Any recommendations?

worthy citrus
sage radish
# worthy citrus I was not able to make it work, either in editor or during command line building...

There is also an undocumented API to hook into assembly post processing called IL Post Processing. Many Unity packages, like Entities and Burst, use it, and some third party plugins too, like Mirror Networking.
It works in both the editor and builds and runs in parallel with other IL processors in parallel.

There's some information about it here:
https://forum.unity.com/threads/how-does-unity-do-codegen-and-why-cant-i-do-it-myself.853867/#post-5646937

silver pendant
#

This is a bit specific but, if I instantiate an object inheriting from PointerManipulator in an EditorWindow, after closing the window, does the Pointer Manipulator persist in the editor or does it get deleted?

#

Apparently they persist until a reload of the editor

deep jasper
#

so, my idea is to support modding in the game. I provide users with a kit to modify each 64x64 cell individually, and i keep 512x512 alpha map on each cell for modders to paint textures on the terrain.

When I start the game, I merge 8x8 cell grid(where each cell is 64x64) into a single 512x512 chunk so I get 64 times less objects on the scene at the same time. These big chunks have increased alphamap/heightmap resolutions to match the quality. So right now with 512x512 alpha maps on each small cell i get 4096x4096 final alpha map.

deep jasper
#

So i decided to make is so when game starts, alphamaps of all terrains are on lowest quality i allow(256 on a giant chunk)

#

and only ones which are close have the entire 4096

#

but that means i need some way to dynamically rebuild the alphamap as player approaches the chunk, and well, rebuild it not to 4k all the time, but to 512/1024/2048 versions based on distance

#

i made the distance code with some workarounds and it works fine

#

but the only part left is the actual map building

deep jasper
#

i can probably load pieces from asset bundle, change their map to a lower one and then go for building as i do rn, but with lower-res

jaunty swallow
#

Making objects static or using GPU Instancing doesn't seem to affect my batch count at all, although I'm changing a lot of objects

#

only saved 2 when pretty much the entire scene's meshes are static

deep jasper
#

isn't it saving only if you have same mesh/material a lot

#

also make sure your static batching is enabled if you are using static objects, or disabled if you are using gpu instancing(not sure but afair static batching should be off in that case)

jaunty swallow
humble girder
#

can some1 help me for making a good isometric placement system? unity 2D

#

ive been lookin everywhere

untold moth
sly grove
regal lava
#

but making your own world grid is fun

humble girder
#

Cause like

#

I want it to be able to have a grid at a custom size

#

And make it to be able to place gameobjects

#

And move em

wet sail
#

is there a way to make unity serialize an external class (from external dll) so that i can see it in inspector ?

upbeat path
wet sail
#

no its from external dll unrealated to unity

upbeat path
#

custom editor

wet sail
#

painful

#

cuz many classes

upbeat path
#

tough, take it or leave it, up to you

wet sail
#

no lib out there that does it for u?

#

i searched with no luck