This question is quite broad since you don’t ask for a specific problem but countless sub issues in one question. This can’t be answered clearly as this would require writing several pages or posting a full example (which would be equivalent of writing your code for you).
I’ve actually created a logic circuit simulation several years ago in Unity. Though i created everything procedurally and everything was basically drawn using vector graphic (even the text). You could actually create components and reuse them. Those could even be nested:
The only elements that actually existed was a “not gate”, an input pin and an output pin as well as a “link”. The actual idea behind this small project was inspired by the redstone torch of minecraft. It’s the only logic gate that exists in MC. Since a piece of wire acts like an or-gate you can build anything else from those.
From the OOP point of view there were essentially those classes:
- CompoundGate (essentially the workspace but could also mean a nested object. So one purple box)
- Output (one red circle)
- Input (one green circle)
- NotGate (the only logic gate)
- OutputPin (Just a pass through gate which spawns an output to the outer world)
- InputPin (just a pass through gate which spawns an input from the outer world)
- Link (one connection between an Output and an Input)
One CompoundGate had a list of gates (NOT-gates / inverters, inputpins, outputpins) as well as a list of Links. So a link was an actual class instance. Each Input could be connected to several outputs. This acted like a an implicit or gate with galvanic isolation. So if two outputs go int one input, the signal of output one does not back propergate to the other output. So an input is always only an input. So both, Inputs and Outputs had a list of Links. The actual simulation was completely “request based”. So if you read an output value (that was a property of input / output) that request got simply forwarded to the connected links which read their values from the other connected output. Though if you allow circular connections this would have caused an infinite recursion. That’s why i had an update counter reference. If an output was already evaluated this update, it’s not updated again.
This was only a very brief introduction into the simulation part. How the user interactions work is a completely seperate topic. Each element could be moved around with drag and drop and rotated freely. Each GUI element which includes the input and output elements (the green and red circles) did handle keyboard and mouse events themselfs. The whole thing was processed and drawn from OnGUI and i actually got decent performance for quite complicated circuits. (I had build 16 bit shift registers with parallel load and read, 8 bit memory, mux / demux, 8 bit binary counter and some other small things, all simulated in one workspace).
How you want to organise all your graphics is up to you. Depending on how complex circuits can get you have to decide if you want to represent each element (gate, link, …) with a seperate gameobject or if you just use ordinary classes (like i did). My scene was actually empty. I only had a camera that didn’t render anything with a single monobehaviour script. Everything happend in ordinary classes.
So what userinput method you want to use depends on how you represent / visualize your gates and links. If you use the UI system you want to use the EventSystem to react to mouse down and drag operations. If you actually represent them with some sort of meshes you may want to use the ordinary Input class to process mouse or keyboard events. Generally dragging of elements as well as connecting pins should be handled by a single script on the camera. It has access to the projection as well as all necessary events. If you don’t know how to implement some kind of immediate mode event system, just look at how Unity’s immediate mode GUI system works. If you need some reference material, read my crash course. The important concept is the “hotControl”. So whenever you have a mouse down event on an element, this element becomes “hot”. If it’s a pin you essentially start a linking operation. When you release the mouse button on another valid pin a link is created between the “hot” object and the one the mouse up was registrated on. Clicking on other elements just start a drag and drop mechanic. I also had box selection support, however this quickly becomes quite complex.
So to sum up: your question is way too unspecific and includes way too many aspects to provide a clear answer. The whole thing can be seperated into the 3 major fields which essentially represent the MVC pattern: The logic representation (Model) which is only about the actual functionality of your simulation and how the different parts interact with each other. The visual representation (View) of your simulation. This could be UI elements, Meshes, custom GL draw commands, … And finally the business that glues all together which includes reacting to user input and manipulating the components.