I know you can attach one script to multiple objects, but I want to attach a script that allows for data sharing between game objects. I wish my Unity game to connect to a 3rd party software over a custom network This way I can update data across Unity and that 3rd party application, and that is why I need access to shared data between game objects. As you can guess, the network code is custom and implemented in C# sockets because I don’t know if I can use the built-in network support in Unity for connecting to a 3rd party software.
Anyway, my own custom network code is at the moment in one script file. In order to avoid having X number of socket connections for X number of game objects, I would like to have only one connection and shared data in that one script. And that is what the drawing above illustrates. Is it possible to attach the scripts in a way so they are shared, or is there another way I don’t know of?
you could use static when declaring the object.
Then there will only be one copy of such object.
For example: I have a script called “tank”
I want all tanks to become lvl 2 when I research lvl 2 tanks
my tank has this
static int level = 1;
so in the middle of the game, I just say tank1.level = 2; And all tanks will be lvl2
you can also do tank::level = 2 in c++, but I’m just starting with C# and I dont know how to do that yet… sorry.
Yes, that would solve the instantiation problem by eliminating X number of scripts for X number of objects. But do I still need to assign the script containing a singleton class to every game object I want accessible?
Thank you for your input but I believe your solution isn’t what I am looking for :(. I want to have game object data stored in one script, so that I can update the objects separately from only one script. This is because I don’t want hundreds of socket client connections to my 3rd part software :).
Let me explain:
I have 2 objects in my scene: Tank1 and Tank2
I am currently in my 3rd party software, where I can control the tank leveling
I change the level of Tank2 to level10
Instructions are sent over my network and caught by the receiver in the script
My code would then have to parse the instructions, containing the tank name and the property to be changed along with the new property value
After the parse, I have identified which object needs to be updated: Tank2, with a property change - Level: 10
The code would then access the game object belonging to Tank2, and change the level property to 10
This behavior allows me to have communication going the other way as well, but I take one step at a time
I got it partially working now However, there are still some unresolved issues:
I can update other objects only and ONLY if I call the object’s GetComponent function from inside the Update function. If I call it from the another function in the same class where Update is placed, I get an error saying unknown type of component. Any workaround for this?
My custom network code is based on a simple socket stream. Streams require a loop, so I made my own thread where the network code is running. The game works fine first time I launch it. After I go back to the scene view and try to go back in game view, it freezes. I suspect this is due to no thread termination from inside Unity, and I need to exit the application completely before I can launch it again. Is there a place I can put code for manual thread termination? Like some script that runs on transition between scene/game view for example?
Thanks for help so far, I hope I get this working soon.
Edit: Tried with a destructor, it did not work. By the way, everything is coded in C#.
public class ThreadScript01 : MonoBehaviour
{
float currTime;
bool helper;
bool mainLoop;
bool destroyed;
// Destructor for thread termination
~ThreadScript01()
{
destroyed = true;
}
// Use this for initialization
void Start ()
{
new Thread (StartMainLoop).Start ();
mainLoop = false;
helper = false;
destroyed = false;
currTime = Time.time;
}
// Update is called once per frame
void Update ()
{
if (mainLoop == true) {
if (helper == false) {
GetComponent<TextMesh> ().text = "Hello";
if (Time.time >= currTime) {
currTime += 2.0f;
helper = true;
}
}
if (helper == true) {
GetComponent<TextMesh> ().text = "World";
if (Time.time >= currTime) {
currTime += 2.0f;
helper = false;
}
}
}
}
//function which starts the text-shifting and makes the thread run until cancelled by the destructor
void StartMainLoop()
{
Thread.Sleep(5000);
mainLoop = true;
while(destroyed == false)
{
//empty for testing purposes
}
}
}
So, after I enter game view, StartMainLoop() will run because it is set-up as a new thread in the Start() function. It will then pause for 5 seconds before it sets a state variable which executes the code in Update(). This is just a simple text-shifting code allowing me to see if the thread was started at all and if it was running. Now, everything works well except the “ending”. I suspect Unity is not terminating custom threads started by users, so I tried with a destructor as you can see (without luck). Hope this code gives a bit more insight into the problem. The reason why I need the function StartMainLoop to run in a new thread is because the network code is a stream and thus has to run continuously. Any suggestions on how to approach this “thread-termination” issue?
I may be incorrect in my thinking, and if so someone please correct me, but I can understand why you are having your socket open and running in the separate thread; though I can see where issue could arrise if you are trying to set a component value from within your thread.
From what I understand, Unity runs within it’s own single thread, and you trying to modify that data from outside the thread without anyway to check if Unity has current access could cause your application to throw a fault code. If you are needing to modify a component in any fashion from within the thread, I would have a look into using a messenger system to send out a message request from the thread and have the message processor, which would be in the default Unity thread, process and update the component.
For your issue with destroying the thread, I would look into storing a member reference to your thread object and then instead of using a destructor method, the MonoBehaviour class that you are inheriting offers you the methods OnDestroy and OnDisable that I would consider having your thread reference call the Abort method to stop your thread from running.
About the message system: I won’t use anything complex. The messaging between the Unity thread and my own thread is consisting of booleans as messengers. I have used this system in the Source engine for a few years, and it never threw a fault. It will however throw faults if you don’t know what you are doing :P: for example calling the MonoBehaviour :: Update function from my own thread. This will cause an exception because Update is always busy (every frame), and my thread is calling this function while being busy/locked.
When I get some time, I will try it out with MonoBehaviour class members OnDestroy and OnDisable. Hopefully this can suspend or abort the thread :).