#I already tried that

1 messages · Page 1 of 1 (latest)

umbral yarrow
#

Can you show me all your code related to this? I need to see where you're adding the listener and where Amount() belongs.

rapid estuary
#

alrigt

#

the whole file?

umbral yarrow
#

yes.

rapid estuary
#

Everything worked literally yesterday

umbral yarrow
#

confirm.onClick.RemoveListener(() => { Amount(); });

rapid estuary
#

Mhm

#

What about it?

umbral yarrow
#

So if you run this code right now, "test 2" never gets printed to the console?

umbral yarrow
#

Does React get called?

rapid estuary
#

Obviously

umbral yarrow
#

hmmm

#

i am really not sure...

#

Why can't you just

#

in the inspector, assign the button's onclick event to Amount()?

rapid estuary
#

one of the reasons is that the gameobjects that call it are clones

#

it's just that I can't

#

It's the only solution and I have no clue why it doesn't work and I'm so fucking pissd kill me

umbral yarrow
#

okay one more thing to try

rapid estuary
#

wait I will do some analysis since I got the old version of the file as well

umbral yarrow
#
void Test(string someText) { Debug.Log(someText); }
...
button.AddListener(delegate { Test("Hello World"); });
#

does this work?

umbral yarrow
#

yeah i'm not sure then... you could try making a small dummy script that just forwards calls to Amount() and set the OnClick event in the inspector to call the dummy script.

rapid estuary
#

im having a meltdown rn

#

why

#

you think it might be an unity bug?

umbral yarrow
#

Wait you're calling React() everyframe?

#

That means you're adding a listener, every. single. frame?

rapid estuary
#

no

#

fucking

#

this bot sucks

#

if this is met ^

umbral yarrow
#

Are you trying to make it so the player can only click the button if a condition is met?

rapid estuary
#

yes

#

and till yesterday it worked

#

like holy shit the only thing I changed is that I fixed some UI bugs nothing else

umbral yarrow
#

Why not just set button.interactable to false when they shouldn't be able to click it?

#

OR

#

Always let them click it, but check the condition in Amount() ?

rapid estuary
#

but it worked before

#

I don't know what made it not work

#

and I'm furious

umbral yarrow
#

are you here to solve your problem or continue to be mad and solve nothing?

rapid estuary
#

hold on let me restart unity it looks like a unity problem tbh

#

nope

umbral yarrow
#

If you're not willing to take a different approach then I'm not sure how to help you any further

rapid estuary
#

it's hard to explain

#

I require this

#

fucking hell

#

@umbral yarrow would you mind if I sent you the entire file

umbral yarrow
#

Haven't you already in that pastebin?

rapid estuary
#

Not file

#

Project

#

The entire unity project

#

I have no fucking clue whats wrong

umbral yarrow
#

uh no. I'm not interested in downloading your unity project, sorry.

rapid estuary
#

ok why isn't it working I have no clue

umbral yarrow
#

@onyx ferry there's a thread for his issue already here.

#

@iron cloak you too.

#

they've linked their code above

iron cloak
#

Amount() is quite a big function that could die in a couple of ways. If there's an error in there, it might be silently dying without finishing the function. Try this. Add this debug log right before you call the AddClick:

Debug.Log($"Adding a listener to {confirm.gameObject.name}");

and then inside of Amount(), put in this log and comment everything else out. Let's make sure it can call the function first.

Debug.Log("Amount has been executed");
rapid estuary
onyx ferry
#

Update, Instance IDs seem to be different between Inspector and code, so betting on a bad reference

iron cloak
#

I don't know how this is running, but I'm making a wild guess

rapid estuary
onyx ferry
#

How are you getting a reference to the button?

rapid estuary
#

using public Button confirm;

#

I attached the button to the script, yes

onyx ferry
#

Okay, so create another field of the same type, drag-drop the button (make sure it's the correct one), and in the code, log if confirm == subject where subject is the field you just created.

#

Prints out false? You have a bad ref

rapid estuary
#

alright

#

wait

#

okay so the ID is the same when it comes to button

#

button component ID: 20138

#

it's the same

#

my bad

#

it doesn't explain why it doesn't work though

onyx ferry
#

Does some of the code run on another thread? If you're not dealing with threads new Thread, async/await, it's a no

#

(coroutines are not threaded)

rapid estuary
#

nope, I'm not

onyx ferry
#

So, right before you add the listener, throw new Exception("Test"), same thing in the Amount method

#

If you don't get any exception, then the code that adds the listener isn't running

#

(disregard any "Unreachable code" warnings this might create, after adding the throw instructions)

rapid estuary
#

it does throw the first exception (before the listener)

iron cloak
iron cloak
rapid estuary
#

when I click the button no exception

#

nothing

iron cloak
#

Okay, so then the code is definitely quietly dying

#

Comment out everything that isn't the throw

#

/* after the throw
*/ right before the end of the function

onyx ferry
#

After that verification (what digi is saying), you might need to explore if it actually adds the listener. Maybe some silenced error makes it fail?
You'll need to log confirm.onClick.GetPersistentEventCount() both before and after you add the listener. It should be printing 0, 1.

rapid estuary
#

still no exception

onyx ferry
iron cloak
rapid estuary
#

yes

iron cloak
#

How about changing the add listener line to confirm.onClick.AddListener(() => throw new Exception("Test"));

#

Actually hang on

confirm.onClick.AddListener(() => { Amount(); });

I think this should be

confirm.onClick.AddListener(() => Amount());
#

Has that been tried yet?

onyx ferry
#

I have another destructive debug method: making the button reference null after you add the listener, so it catches any modifications made to the button

umbral yarrow
#

oh god was this a anonymous scoping issue the whole time

onyx ferry
#

That shouldn't be an issue, both should compile to the same thing

umbral yarrow
rapid estuary
#

also, the exception was thrown

#

confirm.onClick.AddListener(() => throw new Exception("Test 3"));

umbral yarrow
#

yeah i figured it would

#

hmmm

onyx ferry
#

Three possible syntaxes, have you tried them all?
AddListener(() => { Amount(); });
AddListener(() => Amount());
AddListener(Amount);

rapid estuary
#

let's try again

umbral yarrow
#

If those 3 don't work, I think we try just writing a simple script that has nothing in it other than the code we're focused on fixing

rapid estuary
#
  1. no
#
  1. no
#
  1. no
#

the audacity of this bitch

onyx ferry
rapid estuary
#

I will tommorow if you don't mind. I already spend 8 hours working and got school tommorow.

#

and it's already very late

umbral yarrow
#

damn, i was hoping to have a conclusion to this one 😦

#

i was stumped too

rapid estuary
#

we'll try again tommorow

#

good night

onyx ferry
#

Things to try for tomorrow
Print out listener info
Isolate the issue by writing a new, simple script with a button and a listener to see if the issue lies in Amount or outside of it
Check if the listener doesn't get cleared in between the add and the event raise

rapid estuary
#

morning

rapid estuary
#

or something along the lines of:

#

and I wrote this small script which works

#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{

    public Button confirm;

    void Test2(string someText) { Debug.Log(someText); }
    void Start()
    {
        confirm.onClick.AddListener(delegate { Test2("Hello world"); });
    }
}
#

when it comes to clearing the listener i dont think so

onyx ferry
#

That's what you have in the pastebin

#

So run that loop after you add the listener and see what it says

rapid estuary
onyx ferry
#

confirm.onClick

#

Is the event

rapid estuary
#

tried that

#

doesn't work

#
UnityEngine.Component.GetComponent[T] () (at <0ee480759f3d481d82ada245dc74f9fd>:0)
InteractionRadius.React (UnityEngine.Vector3 center, System.Single radius) (at Assets/Scripts/InteractionRadius.cs:361)
InteractionRadius.Update () (at Assets/Scripts/InteractionRadius.cs:431)```
#

OH WAIT

#

huh

#

ok so error solved but it doesn't debug anything

#

like it doesn't log anything

onyx ferry
#

Log confirm.onClick.GetPersistentEventCount() just before the loop

rapid estuary
#

0

onyx ferry
#

Add a dummy listener and retry

#

Not sure it'll even work, those methods get persistent listeners, the ones added at runtime might not be persistent

rapid estuary
#

still no

onyx ferry
#

So these aren't persitent

#

Onto the next step

#

Remove the dummy listener, and right after you add the listener that doesn't work, set confirm to null

#

Then play the game. As soon as you get a NullRef, stop the game and inspect the line it got thrown on to see if you're messing with the listeners at that point.
If you're not, then put the confirm = null after the point the exception was thrown, and repeat the steps

rapid estuary
#

so like

#

ugh

#

FUCKING HELL

onyx ferry
#

confirm.onCLick.AddListener(Amount);
confirm = null;

#

The troubleshooting stops when you don't get NullRefs anymore

rapid estuary
#

...i'm not getting any NullRefs at the first step

onyx ferry
#

So you're not modifying the button afterwards

#

That is the worst possible outcome

#

The listener gets removed silently at some point

#

Or, it's accessed from another script. Try: DestroyImmediate(confirm), then confirm = null;, and see if you get any errors

rapid estuary
onyx ferry
#

It won't make any difference, but you can add it

rapid estuary
#
InteractionRadius.React (UnityEngine.Vector3 center, System.Single radius) (at Assets/Scripts/InteractionRadius.cs:361)
InteractionRadius.Update () (at Assets/Scripts/InteractionRadius.cs:432)```
#

Debug.Log(confirm.onClick.GetPersistentEventCount());

#

should I comment it

onyx ferry
#

No, you move the DestroyImmediate and confirm = null below that line

rapid estuary
#

ok

onyx ferry
#

After the line that threw the exception

#

The log

rapid estuary
#

NullReferenceException: Object reference not set to an instance of an object
InteractionRadius.React (UnityEngine.Vector3 center, System.Single radius) (at Assets/Scripts/InteractionRadius.cs:362)
InteractionRadius.Update () (at Assets/Scripts/InteractionRadius.cs:432)

#

NullReferenceException: Object reference not set to an instance of an object
InteractionRadius.React (UnityEngine.Vector3 center, System.Single radius) (at Assets/Scripts/InteractionRadius.cs:359)
InteractionRadius.Update () (at Assets/Scripts/InteractionRadius.cs:432)

#

line 362: for (int i = 0; i < confirm.onClick.GetPersistentEventCount(); ++i)

#

Debug.Log(confirm.onClick.GetPersistentEventCount()); line 359

onyx ferry
#

Move the destruction and the set to null after line 362

#

Outside of the for loop (after the loop)

rapid estuary
#

no errors now

onyx ferry
#

This is not after the for loop...

rapid estuary
#

oh after ok

#

my baf

#

dd

#

still nothing

onyx ferry
#

Alright. You said you can't start the debugger right?

rapid estuary
#

yes

onyx ferry
#

So, make a new object with a button on it, and add Amount as the listener like you're already doing with confirm

#

You'll just have to declare another variable to reference the temporary button

rapid estuary
#

still fucking nothing

onyx ferry
#

I'm afraid I have nothing else to suggest

#

Apart from deleting the entire object, re-creating it and linking the references again

rapid estuary
#

object as in?

onyx ferry
#

The one that has the button, and the one that has the script that adds a listener, if they're on different objects

rapid estuary
#

I see. Thanks for your time though

rapid estuary
#

what the fuck

#

@onyx ferry you know what

#

I might as well pay you if you help me

onyx ferry
#

I'm out of ideas

rapid estuary
#

I might send you the entire project ig

#

I mean the only thing I changed

#

is some UI related stuff, aka scale etc

#

nothing

#

fucking

#

else

onyx ferry
#

I would have suggested checking if you can inspect the event with the debugger, to see if you have access to the listener collections, but it doesn't work on your side

rapid estuary
#

so it might be a unity bug?

#

I fucking hate my life

onyx ferry
#

What Unity version are you on?

rapid estuary
#

2020.3.25f1

onyx ferry
#

I have 2020.3.3f1 installed on my side. I'll test some stuff

rapid estuary
#

alright

#

can I send you the file including the project?

onyx ferry
#

Yeah why not, at this point

rapid estuary
#

ok DM since you know, private/confidential stuff

#

I mean not that it's secret

#

it's the files

#

you get the idea

onyx ferry
#

Sure

onyx ferry
#

Okay it's open, I'll need you to guide me through it

rapid estuary
#

Alright

#

The issue is within the InteractionRadius.cs file

#

it is located within the Scripts folder

#

The button which the listener "operates" on is located in the following hierarchy:

#

EventSystem > Canvas > InputAmount > Button

onyx ferry
#

Line 311 of InteractionRadius was for debugging purposes right

rapid estuary
#

I have unity closed

#

which line is it

#

wait nvm I have it open lmao

onyx ferry
#

confirm.onClick.RemoveListener(Amount);, it's in Amount so it shouldn't interfere

#

Unless Amount is called manually, which isn't the case

rapid estuary
#

No it isn't for debugging purposes

#

It worked before though

onyx ferry
#

Alright now, how do I get to that button in game?

rapid estuary
#

here

onyx ferry
#

Getting exceptions when trying to instantiate an element from the periodic table

#

Investigating...

#

ArgumentException: method arguments are incompatible

rapid estuary
#

wait did I send you the database

onyx ferry
#

It printed out elements to the console when starting the game, so I assume that was the database

rapid estuary
#

yes

#

I never had this error though

onyx ferry
#

I have a lot of random ones lol

rapid estuary
#

Oh boy

onyx ferry
#

Editor throwing, shader graph dying etc

rapid estuary
#

May I see them?

#

shader graph out of everything else

#

fucking wonderful

onyx ferry
#

It's not runtime, so I assume this doesn't cause issues

rapid estuary
#

ah

#

Wait did you open the project or did it open straight up the main "Screen"?

#

Like did it open the menu first

#

but that wouldn't change much.

onyx ferry
#

I opened the project by double clicking the only scene file present in Assets/Scenes/

#

Okay managed to fix the instantiate button error

rapid estuary
#

what caused it?

onyx ferry
#

There was a handler in the On Click inspector list that was just empty lol

#

No idea what caused it, removed it and error went away

#

I have the dreaded "Confirm" button in sight now

#

It says "Hello World" when I click it

rapid estuary
#

Yeah it was debug thingy

#

and nothing else happens?

onyx ferry
#

Nope, the screen doesn't go away

rapid estuary
#

let me double check if it has the proper handler just in case

onyx ferry
#

It's added in the InteractionRadius:React method

#

Debugging to see if that executes

umbral yarrow
#

this still didn't get solved? D:

rapid estuary
#

I can feel the evil from this script ten miles away

#

it's the soviets slowing down the progress on western science

#

and yes it's the same listener

#

why the fuck it doesn't work

onyx ferry
#

The listener gets added to the internal listeners array of the onclick event

#

But doesn't get called

#

Debugger never hits the breakpoint

rapid estuary
#

rip

umbral yarrow
#

have you tried just remaking the button/prefab?

rapid estuary
#

yes

#

did absolute jack shit

onyx ferry
#

Okay progress

#

Manually invoking the event in code runs the handler

rapid estuary
#

yayyy

#

Okay so I gotta go guys. See you tommorow!

onyx ferry
#

Ahh I think I got it

umbral yarrow
#

oh please do share

onyx ferry
#

The handler does not run if this is captured in the lambda expression, which means this doesn't exist anymore when the event is raised. And surely, the whole object is destroyed right after the UI button is shown

#

Case solved

umbral yarrow
#

that makes sense, but how is this being captured in a statement like

button.onClick.AddListener(() => Amount()); ?

onyx ferry
#

Amount is a method that's declared on the MonoBehaviour, so to resolve the scope it has to capture the whole class

umbral yarrow
#

So what would be the recommended fix there?

onyx ferry
#

And commenting out the two Destroy calls run the handler!

#

Have a separate script to run the handler on, that never gets destroyed

umbral yarrow
#

ah, that makes complete sense

#

good detective work @onyx ferry 👍

onyx ferry
#

let's gooo

onyx ferry
#

So, full explanation of the story and how to fix.

I started putting breakpoints pretty much everywhere to see how the execution flows through the program.
You can place chemistry elements on a table, and fill these elements with either raw chemical elements, or compounds (like water). Then, if you combine two containers (say one flask of Na and one of H2O), it asks you how many there are to combine, so it does the reaction realistically with the stoichiometry and whatnot. The issue lies there, when you click on the "Confirm" button to combine the two containers into one, the handler does not get run.

After that I focused on the handler addition that worked half of the time, literally. The following worked
button.onClick.AddListener(() => Debug.Log("test"))
While that one didn't
button.onClick.AddListener(() => Amount())

So I moved on and tried this: () => Debug.Log(this.gameObject.name), and suddenly it wasn't getting called anymore. That's pretty much where it clicked: if I included a reference to the script or the object itself, it stopped logging. In other words, if the lambda captured this in its scope, nothing would happen.
The only reason for that to occur is if this didn't exist anymore at the time the event was raised. And with Unity, it means the object got destroyed.
So I scrolled down the method until I hit the dreaded two instructions that caused it all, Destroy(gameObject) and Destroy(other.gameObject).
The handler does not run because there is no object to run it on anymore.

I commented out the two Destroy instructions and played the game again. Added a few containers and components, combined them and the two quantity inputs and the button appeared. I hastily added random quantities and hit "Confirm".
Unity froze. "Oh no", I told myself for a bit. Then I saw it. The Visual Studio icon in the task bar was blinking orange. I switched to it, and to my delight the debugger had hit the breakpoint in the Amount method.

rapid estuary
#

You would make a fortune as a writer

rapid estuary
#

@onyx ferry mind sending me the file that you modified?

#

if you wouldn't mind, of course

#

if you added other stuff to the game itself I would really appreciate the whole project being sent over. And yes, I will proceed to pay you

onyx ferry
#

To respect the "don't distribute" statement I encrypted the files with a random key then deleted them, ie. they're not recoverable.
I have the fix in mind though. You would need to make the Amount method on an object that does not get destroyed, or in a separate class completely, and pass the required info as arguments to the method.
My guess would be on the UI element where you input the quantities and confirm. That one doesn't get destroyed at all. You would just need to store the required info prior to calling it.

#

The subscription can still be done in your React method as long as the lambda does not capture this

rapid estuary
#

fixed it, thank you so much ❤️

#

send me your email so I can send the cash via paypal

onyx ferry
#

You're good. I don't have paypal anyway lol
I've been doing this in my free time for more than a year and never received compensation for it, that's not going to change today