Basically, I have a popup which consist of an image, text and a button. When I right click an object I want the pop up to be set to active. Although it works if there's only one gameobject instance, when you instantiate more than one instance it stops working properly. note: that includes situations where the two gameobjects aren't the same. After several days I am growing desprate. Anyone mind helping me? Would be much appreciated.
#Script not executing properly when there are more than two gameobjects
1 messages · Page 1 of 1 (latest)
best post the code here as well
true
Pastebin
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
where is the script located at?
is it on the instiate or on a different object
Sorry I didn't answer, had a doctor's appointment
np
The script is located on all gameobjects that are dragable
so the instansitated ones
yes
Destroy(objectHit.gameObject);
why do you do this instead of just
Destroy(gameObject);
I did but was told that it wouldn't work
in reality the result was the same
it even worked the same way before the raycast
but was told to add it anyway
where do you call the popup?
what do you mean?
BTW I am going to sleep cya
the popup function with the destroy option
you mean:
private void Start()
{
button.onClick.AddListener(() => DestroyObject());
}```
?
just a message so the thread won't get removed
Hey. I see no one's been helping you out yet.
Since your issue is related to UI and OnClick, I would recommend going through a youtube UI tutorial, and see if you learn anything that might be useful.
If I have time later today, I might freshen up on UI myself and see if I can create a similar solution.
Alright, I will. At the moment I am having lessons so I will do that the moment I'm done
A message so this thread won't get deleted
I am having tons of other work recently so I didn't have time to work on this
i will tommorow though
Alright. A break from the problem might make it easier to solve later
WELL SHIT
Boss told me to make a presentation for tommorow detailing current progress
and concrete dates of milestones
fuck
good news is I will probably get more funding
@stuck plover I hope you don't mind being pingged, but have you got anything?
it's ok for this thread
this is the Unity script?
or unrelated
Alright. I'm busy in a meeting. Will talk to you a bit later.
BTW if you feel you need an explanation for delays - there's that anxiety over the political situation.
true
It might be a couple hours before I can test some code.
I've created a project for the testing, so I can upload it when done.
In theory the solution is simple. Not expecting too many problems.
Just hope it applies to your situation.
Meanwhile - how are you dealing with this snag in your project?
Are you working on other things, or are you researching the issue?
Or have you gone to a dead halt
Depending on the answer, I might have some ideas to help improve your general workflow.
I need a screenshot from the Inspector, of the Canvas component of the panel where your Button is placed
Well, let's just say not long. I didn't even really know how to code in C# until now. This thing is supposed to be a proof of concept so we can get others on board but of course it all went to shit
Alright. The beginner fog and overwhelming factor is very high.
What did you base the script on? tutorial? insight? example?
hmmmm
well
Originally there were no raycasts etc
So I must say that I've written this piece of garbage alone
i mean uh
the pop up part
the first part was based on the tutorial, yes
Since you are very new, a better question in code-beginner could have been:
I am very new to Unity, I have an assignment, and I need <this> functionality. Can anyone help point me in the right direction, or explain how I should do it?
What you presented instead was a problem in a scenario that may or may not be very intricate already - which leads people to assume you might have other things in the project that might be interfering with what you're trying to achieve.
What you should probably do, since this is a proof of concept, is make a compressed archive (rar/zip) of the project, without the Library folder (it will be regenerated), and upload it here
remove any assets that might be considered copyrighted or important to the project
When encountering a problem, the usual approach is:
- Ask where to learn how to fix it
- Do your best to understand, ask for help along the way
With some good guidance - and good listening from your side - you should be able to surmount the challenges that face you.
If you cannot solve it after much effort, you either need to learn more about the basics, or you must investigate your own learning-process for flaws or things you have missed.
There are a lot of regular helpers, online every day, who may seem tedious or condescending, but are really asking you the best questions, at least from their point of view. If they have engaged you in conversation, they are not doing it for casual talk, as they do not want either of you to waste time. (there are some exceptions...)
in your case - if you had done this a few days ago, you could have gone through enough tutorials to become an expert on UI - and perhaps suddenly realize the solution - but at least have learned something useful.
However, I think it might be the if-statements or something
May I ask what concept you aim to prove?
actually, nevermind that question - it's inappropriate for your situation
That such kind of software is actually possible
so far I gather - To click visual elements and interact with them?
if so, should be very doable
I mean generally such a chemical simulation
ah
thats the thing they want me to prove
not sure what you mean about simulation
Which is supposed to do what?
Conducting experiments on computer instead of physically basically
I recall that now. It was mentioned a long time ago
Yup
Alright. I understand. That should be doable.
in case you didn't catch it, I suggested something last time it was mentioned
if you want faster testing, make a short version of that huge file
We came into conclusion that it will be probably better if we just switch to json, since turns out .txt files aren't really good at having stuff like
properties
"Na + H2O": {
"output": "NaOH + H2"
"state": ["liquid", "gas"]
}```
This, for instance ^
ah yes, JSON is the standard and most efficient way
Except on unity it seems to be kind of funky.
Unity handles serialization in its own way. I'm no expert on it though.
Will you be uploading a compressed archive of the project?
I'm off for a bit. Back later.
Sure
alright, remember to exclude the Library folder - it takes the most space
what's the size?
Google Docs
I believe I may have found the issue.
It might be faster for you to test it, if you are here right now.
I am
Alright
Theory:
First, a fact: You only need one instance of this script in your entire scene
What you have done, is place a DragObject script component on each of the prefabs.
That means there are multiple instances of the script in the scene.
I noticed the debug logs were different in the case of clicking an object when there were two objects in the scene
and then I tried a third object
I'm pretty certain this is what is happening:
2 instances of DragObject run simultaneously
You click the mouse button down
Script A runs Raycast, runs checkIfPressed(), finds image to be __in__active in hierarchy, sets it to true
Script B runs Raycast, runs checkIfPressed(), finds image to be active in hierarchy, sets it to false
Solution:
Remove DragObject from ALL prefabs, and ALL other objects
create a new object in the scene, an empty game object, name it DragObjects
add DragObject to it
Play scene, try it out
But hm
wait
I understand now
You are using OnMouseDown() and OnMouseDrag()
which logically requires them to be On that game object
I guess one solution would be to split those two into two seperate scripts?
Yes, like so:
DragObject becomes the controller
It needs mzCoord and other stuff to be public
then make a script named something like DraggableObject
and add the code from OnMouseDown/Drag
and adapt it to work with DragObject
actually
since all the prefabs already have DragObject
rename it DraggableObject
and make DragObject - copy over all the code, except the OnMouseDown/Drag
Alright
or not rename - might cause issues idk - and just make DragObjectController
overthinking 🤔
But I am pretty sure this will solve your problem
let me know if you hit any snags 👍
I can write down more simplified instructions
👍
oh
- Rename old script to DraggableObject
- Create a new C# script named DragObject
- Copy all the code from DraggableObject into it
- Then modify both scripts accordingly
DraggableObject (which is on all the prefabs to be dragged)
- Remove all Functions(), except Start() OnMouseDown() and OnMouseDrag()
DragObject
- Take the variables used in OnMouseDown() and OnMouseDrag()
- Make them [HideInInspector] public
(get set properties are better, but no need for this example) - Remove the OnMouseDown() and OnMouseDrag() functions
Then, in DraggableObject
- Modify OnMouseDown/Drag to use the variables in DragObject instead
DragObjectController must exist on an empty game object in the scene
what is it called now?
DraggableObject
alright
you can choose whatever you like
It's like my conciousness left my body
I can change the instructions for the ease of it
I forgot how to type
DragObject it is then
yes
alright, sec
Quick question though... Why leave Start() in DraggableObject when it was only used for the listener?
actually,I was going to say, I wasn't quite sure of that one yet. Do what you think is logical.
Well we'll see. If that won't work I'll just switch the place.
I'm rusty on UI, but getting around to it whenever I finish this line renderer stuff
I fixed the instructions with the renames
Alright, just to verify:
[HideInInspector]
public GameObject image;
public Text compoundName;
public Text extract;
public Button button;
public Camera cam;
Might be a simple question but a single error can cause a chain reaction of doom
Not quite
You are using those fields to get references - they need to be in the inspector
what you need to do
is make mOffset and mZCoord public, but [HideInInspector]
[HideInInspector] public Vector3 mOffset;
because you don't need it in the inspector, but you need it to be publicly accessible by another script
actually
I just realized
Might as well make a public function instead, in the controller
for one good reason
the controller script might run its Update before the OnMouseDown of the other script runs
so you should add the code from Update into its own function
[HideInInspector] public Vector3 mOffset;
[HideInInspector] public float mZCoord;```
so like this ^
dont mind private
and then create another function, which is triggered by OnMouseDown etc
Another thing -> OnMouseDrag - can't you place all the code from both function calls, into OnMouseUp ?
or just from Drag to Up
nah nvm
no need to touch it
alright
I'm going to write a short outline of what you need
Hold on as stuff is getting confusing. I was supposed to use [HideInInspector] in the original file, correct?
sec
Yes, mzCoord and mOffset needed to be hidden
However, by creating a Public function() you don't need to do that
using UnityEngine;
public class example : MonoBehaviour
{
private DragObject dragObject;
private void Awake()
{
dragObject = GameObject.Find("DragObjectController").GetComponent<DragObject>();
}
private void OnMouseDown()
{
float coord = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
Vector3 offset = gameObject.transform.position - GetMouseAsWorldPoint();
dragObject.Clicked(coord, offset);
}
private Vector3 GetMouseAsWorldPoint()
{
// Pixel coordinates of mouse (x,y)
Vector3 mousePoint = Input.mousePosition;
// z coordinate of game object on screen
mousePoint.z = mZCoord;
// Convert it to world points
return Camera.main.ScreenToWorldPoint(mousePoint);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DragObject : MonoBehaviour
{
public GameObject image;
public Text compoundName;
public Text extract;
public Button button;
public Camera cam;
Vector3 pos = new Vector3(200, 200, 0);
private Vector3 mOffset;
private float mZCoord;
Transform objectHit;
private void WasClicked()
{
if (Input.GetMouseButtonDown(1))
{
RaycastHit hit;
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
LayerMask mask = LayerMask.GetMask("LabEq");
Debug.Log("0");
if (Physics.Raycast(ray, out hit, 100, mask))
{
objectHit = hit.transform;
checkIfPressed(objectHit);
}
}
}
void checkIfPressed(Transform save)
...
void DestroyObject()
{
Destroy(objectHit.gameObject);
image.SetActive(false);
}
void Clicked(float mzCoord, Vector3 offset)
{
mZCoord = mzCoord;
mOffset = offset;
WasClicked();
}
}
ah, wrong rewrite of the first segment
maybe not
nah it's good
I need a break lol
didn't include the Start() segment in either of these
but I guess you need to include that one
are you using DestroyObject() ?
added GetMouseAsWorldPoint() to the first code segment - had forgot it
I can already see - I have messed up one or two things
pardon the derp, it's been a dense day
I haven't properly understood what you've done with mZCoord
Let me know if frustration hits a level that requires a reset of complexity
This is DraggableObject, yes?
Hold off on the examples
I might as well rewrite the entire thing, 'cause every time I thought I nailed it, there was something I missed
but the solution is right around the corner anyways
I just now realized what you're doing with mZCoord
I think it can be deleted alltogether
gonna have an example soon
yeah, might as well
alright
eat something etc
prepare documents for the meeting tommorow
Yeah that'll be a good idea
And you know what
I'm pissed
As it turns out
I gotta rewrite the database again
how so?
AKA convert it into JSON
Because it doesn't contain properties
And I despise JSON in C#
well, it will be worth it
and hopefully you'll find a procedural way
let's hope so
it should be possible - just need to find where the solution is
I will think about it when we fix this issue though haha
sec
if this isn't the solution, I might need an hour to cool off
using UnityEngine;
public class DraggableObject : MonoBehaviour
{
private DragObject dragObject;
private Vector3 mOffset;
private float mZCoord;
private void Awake()
{
dragObject = GameObject.Find("DragObjectController").GetComponent<DragObject>();
}
private void OnMouseDown()
{
mZCoord = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
mOffset = gameObject.transform.position - GetMouseAsWorldPoint(mZCoord);
dragObject.Click();
}
void OnMouseDrag()
{
transform.position = GetMouseAsWorldPoint(mZCoord) + mOffset;
dragObject.image.SetActive(false);
}
private Vector3 GetMouseAsWorldPoint(float mZCoord)
{
// Pixel coordinates of mouse (x,y)
Vector3 mousePoint = Input.mousePosition;
// z coordinate of game object on screen
mousePoint.z = mZCoord;
// Convert it to world points
return Camera.main.ScreenToWorldPoint(mousePoint);
}
}
using UnityEngine;
using UnityEngine.UI;
public class DragObject : MonoBehaviour
{
public GameObject image;
[SerializeField] private Text compoundName;
[SerializeField] private Text extract;
[SerializeField] private Button button;
[SerializeField] private Camera cam;
private Transform objectHit;
public void Click()
{
RaycastHit hit;
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
LayerMask mask = LayerMask.GetMask("LabEq");
Debug.Log("0");
if (Physics.Raycast(ray, out hit, 100, mask))
{
objectHit = hit.transform;
if (!image.activeInHierarchy)
{
Debug.Log("1");
image.SetActive(true);
image.transform.position = new Vector3(objectHit.position.x, objectHit.position.y + 3, objectHit.position.z);
if (extract.text != "Result")
{
Debug.Log("2");
string[] phase1 = extract.text.Split('→');
string[] phase2 = phase1[1].Split('+');
compoundName.text = phase2[0];
}
else
{
Debug.Log("3");
compoundName.text = objectHit.name.Replace("Lab(Clone)", "");
}
}
else
{
Debug.Log("4");
image.SetActive(false);
}
}
}
}
I made it easier to see what mZCoord is used for
and I condensed the functionality of DragObject
into a single function
I also made only GameObject image public, since none of the others need to be accessed via scripts (as far as I know?)
you can change those back - but they will still be available in the inspector like this
if other scripts use those variables, make them Public again
by the code in this solution, it is expected that the DragObject script is on a GameObject with a specific name
GameObject.Find("DragObjectController")
z No definition of Click
oh wait
lets see
dragObject.Click(); means Click is on the dragObject component, which is the controller script
it is public, so it can be accessed by other scripts
And on DragObjectController I need to put?
alright
Wait, I need to put DraggableObject in it as well?
the DragObject script segment is the 'controller'
DraggableObject is the script which is already on all the prefabs
it has OnMouseDown etc
because object logic
So I don't put DraggableObject in there?
the DragObject script should only exist on one object - an empty game object named DragObjectController
Aight
this avoids the problem of "too many chefs in the kitchen"
only one guy is allowed to perform the action - the others let it know when they need it
Andddd it isn't working
did you assign inspector fields?
Yes
screenshot Unity, with the Hierarchy visible, and the DragObjectController selected
check the script component of the prefabs
Only DraggableObject
screenshot the component section
As in the inspector?
yes
Alright, I'm testing on my side
When I renamed the script which was on all the prefabs
I needed to reassign the script on them
It didn't happen on my part, huh
i can move it around
but I cant right clikci
also for some reason if I left spawn click it it pops up for a milisecond
I noticed the exact same thing
the bug is gone, but a new one is introduced
welcome to game design 🥳
let's see if I can see the logic in this
if I can't, I'll see if anyone else can help, since we have come so far
I hope I am not taking up your precious time of course
it's educational enough
besides, I have 800 Lines of code staring me down from the other side of the room
this is fine
:)
Now you're making me feel guilty haha
I have no time pressure, it's fine
my own cursed projects
LineRenderer having me going in circles
I made a very precise clock, though
it even ticks, and I can speed it up, and it will still display time perfectly (analogue)
_
Issue Update
Old script - https://gdl.space/iyetiwusec.cs
Was placed on all prefabs, and the function was called at least twice, which negated its function
Right-click correctly displays the popup, if only one object has spawned.
New solution:
Script A - DraggableObject - is on prefabs.
Script B - DragObject - is attached to a single empty game object in the scene
When the object of Script A is clicked, it uses the public Click() function of Script B
Right-click almost never displays the popup
A - https://gdl.space/nohimuribu.cpp
B - https://gdl.space/yifesomewa.cs
I should post it on #💻┃code-beginner , correct?
Let me double check the rules lol
Yeah, should be fine
or wait
don't post this post
@wispy niche
Ask for help to the Thread
Say we have an updated issue description
When asking for help in the channels - spend some time to make one very well composed post - so it is easy to see it
you can also link to the thread with name by using #
But for now, it's done, wait at least an hour
I already found two faults in the scripts
not sure if related
I may have realized a much more simple fix
go on..
ah I see
It does work
oh wow
There's just some mess with the logic, because sometimes it registers the image as active during the click
huh
this is what changed:
instead of every flask waiting for input from the mouse - only the one which was also clicked, can run the function
no definition of "Click"
oh.
well um
There's an error
But not sure if I should change it to public
(click variable)
the image is only set to false when the object is dragged, or if you clicked an object while the image was active
let's see if I can remove this bug
but hey, it works for a demo :)
error where?
if you copied the entire script from the link, and pasted it into DraggableObject
mind that the script you copied is named DragObject
I didn't paste it into Draggable
so manually rename the class you pasted, into DraggableObject
the original script was on all prefabs
you'll need to reassign the inspector fields
if you Enable the game objects in the hierarchy, you can use the Reset function of the script component - as I made it get all the objects automatically
must be done for each prefab
nah wait
I did not do that for this script xD
private void Reset()
{
image = GameObject.Find("popup");
compoundName = GameObject.Find("Tag").GetComponent<Text>();
extract = GameObject.Find("result").GetComponent<Text>();
button = GameObject.Find("destroy").GetComponent<Button>();
cam = GameObject.Find("Main Camera").GetComponent<Camera>();
}
add that
to fix the last bug - clarify this for me: When does the popup need to be disabled?
when it's moved or right clicked again
does the position of this part matter?
No
Well, I can't right click it again unfortunetly
I posted an update in code-beginner
this script works, but still has the bugs described
after all this - I wonder if there is an even better solution.
Just not sure about MouseDrag
but I finally need a break for today
You can use this for demonstration, if you can get it working like I did
(if it fails) just download your zip from the google drive, edit that script, should work immediately
Aight, tym man
a generally good tip, is to avoid using all the different calls on MonoBehaviours
and just use a hierarchical structure for execution
*tysm
Got it.
Later tonight or tomorrow, I'll look into replacing OnMouseDown/Drag with Raycast
Drag is basically the same as Input.GetMouseButton - which is only true between MouseDown and MouseUp
I made a better fix
only a minor issue left - if you click to drag the item, and click a bit far off the item, the UI is not disabled 🤔
place this script on an empty game object in the scene
comment out everything in the prefab script - except the variables that hold the references (who knows, might need em)
Actually, I can't believe how many mindfucks there are - by doing the last two things I said - it doesn't work 😂
but if you just change the content of the original script - it will
Apparently - I only believe I'm sane today - I have reverted my script back to how it worked when I made the video
Not sure what is wrong with the one I linked you
but I will fix this after a good night's sleep
tldr; I fixed it, then broke it, then fixed it again
No, I recorded the video, then made final changes, which seem to have messed it up, so I reverted the script back to a functioning state - I have not uploaded the fix
what
that doesn't make sense
unless you're lacking codecs
try VLC
or just nvm, it just shows that objects can be deleted like crazy
When is your presentation?
Or, how long do you have to make a better demo? I have time now
fixed it
This script only needs to be on one game object in the scene
The only bug that remains, is that if you drag an object from clicking beside it, the UI will not disappear.
This can be improved by some better logic, or perhaps just giving the Popup objects a Tag - right now it is identifying the button based on Layer == UI
@wispy niche
Having lessons atm
Will see in a sec
Btw, finally managed to make the json work
after like uhhhhhh
two months
yes
I know where to go for help then 😉
hah
So, simply an empty gameobject?
Yes
in order to disable the prefab script, just comment every line
except the public variables (you want to keep inspector references in case of things)
To comment or uncomment all selected lines ---> CTRL + K + C or U
Aight
btw, quick question
can you move 2D objects with this?
Like an image for example
the way it's coded now, it doesn't differentiate between objects - so I believe it could drag anything
You could have a Layer named Draggable, or a Tag
is the target object Raycastable?
I just asked in code-beginner
Since UI elements have a RectTransform instead of a Transform
you have to reference the RectTransform's position
might be a bit more complicated, due to UI hierarchy
not sure if you can calculate the position in the same way
but it is possible, as long as you compensate properly
Yeah, we did solve it :)
Ask if there's anything about the code you don't understand.
Other than that, you can probably close this thread and engage in the main channel.