I'm working on an Unity3D application that basically fetches data from a server and attempts to create objects at runtime. When I'm trying to create this objects, via a constructor on some classes I have defined, I get the following error:
get_name can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function
I can't move this to either Awake or Start since I need some feedback from my GUI (user credentials) before I run the mentioned code.
Any ideas/suggestions?
You can't create objects in your constructor or you will get that error. In fact, you should eschew constructors in general with Unity and favour Awake/Start/etc.
I don't know what you're doing, but there's no reason why you can't Instantiate() the object somewhere in your code, set it up properly on the next lines of code, and then let it's Awake()/Start() take place after that, letting it be fully initialized.
I was able to make it work. Here's a summary of what I did:
Made the class instantiating the classes at run-time, referred as Creator, extend ScriptableObject. This allows to start the Creator class on demand using CreateInstance.
Change the Creator class methods, variables and the class itself to static.
When needed intantiate the Creatorclass via CreateInstance.
Make sure to call the methods that do the class instantiating from Start, Awake or Update as appropriate. In my case it was Update.
Related
I'm creating a game where the player creates objects (blocks) in a "set up" scene and then when the timer ends, I'd like those objects, including their transform values to be loaded into a new scene. How would I go about loading objects created during runtime into a new scene?
DontDestroyOnLoad is a valuable way to achieve this.
What you could also do is the following:
Create an Empty object called "Cross-Scene-Objects" and add a script to it, make it so it doesn't destroy on load. Then simply child any objects to that object, and remove objects as you see fit.
You could also make the CrossSceneObjects script a singleton class and have some basic AddObject and RemoveObject methods which handle putting the game objects under the object.
If you only want certain objects in certain scenes, you could use the method above but add some further logic to set game objects active if you're in the scene you want them to show up in.
I have no example code, but if this is not enough for you to work off I can happily edit to provide code examples :) My style is to first provide the solution steps rather than the code to give you a starting point.
What's the different between:
UpdateAsObservable()
EveryUpdate()
in UniRx?
Are they the same?
Observable.EveryUpdate is defined as a static method, so it can be called from a place other than MonoBehaviour. Internally, the execution timing of CoreThreadDispatcher's corruption is notified.
For your reference, you need to be careful when using the IDisposable of the subscribers correctly (you will need to paste AddTo etc.)
ObservableUpdateTrigger is defined in the UniRx.Triggers namespace.
If you leave UniRx.Triggers outside of Using, you can call UpdateAsObservable () directly.
The entity is the ObservableUpdateTrigger
AddComponent is automatically added to the call at the time of the call (you do not have to worry about the presence of the trigger when you actually use it)
ObservableMonoBehaviour and internal structure are the same
I have a persistent game object that I use to initialize basically everything. The script Persistence as I call it has some public references I just dragged on them via the inspector.
I'm trying to make it persistent like I found online:
public static Persistence instance;
void Awake()
{
if (instance != null)
{
DestroyImmediate(gameObject);
}
else
{
DontDestroyOnLoad(gameObject);
instance = this;
}
}
The thing is, when I load a level from main menu, it's fine. When I load back the main menu from that level, it says
MissingReferenceException: The object of type 'Persistence' has been destroyed but you are still trying to access it.
So I decided to let it create other instances when loading the main menu, but that messes up all the scripts on the game levels that rely on this data.
My question is, how to correctly implement this ~singleton persistent pattern in Unity, given I have inspector-added references?
NOTE that I initialize only from my Awake function in my persistent class and from nowhere else. Literally, my InitializeMe scripts are called from the Persistence class, one after the other.
What should I do differently to make this work? Initialize from a different, non-persistent gameobject? Forget dragging to the inspector? Any advice to make this work is appreciated.
I got it to work. So here's the thing one should know (I should have known) before messing around with persistence in Unity:
You don't drag references to a persistent GO via the inspector as they are gone the instant another scene is loaded except for additive loading. Also the persistent GO may hold data relevant to multiple scenes, hold functionality that is built for general purpose, as reusable as it goes, but it never initializes anything itself or interfere with non-persistent GOs other than being called - used as a tool - or providing the data.
This arcane wisdom is mine though, so anyone more skilled reading this, please do correct me if I'm wrong before others take this to heart.
So to be exact, I made a non-persistent master INITIALIZER that does the exact thing. I get all the scene GOs into a collection once and no GameObject.Find again. I used LINQ queries to conveniently filter my results from that collection. Another thing was my InitializeMe abstract class (or to be more precise, its descendants).
public abstract class InitializeMe : MonoBehaviour
{
public int orderNumber;
public abstract void INIT(INITIALIZER init);
}
here orderNumber is used to determine the order of the initializations, should one object depend on the other. It also worths mentioning that doing like so can result in a very predictable way to setting things up, as it is done one after the other. Note that this doesn't create a bottleneck, because Unity's scripting API only be executed in the main thread - dividing the code into multiple Awake or Start methods wouldn't perform better to my best knowledge as of 2017. It is used by a LINQ query in the INITIALIZER.
The good thing in INITIALIZER is that - again - it holds itself everything, including a reference to the persistent object and the save data as well, so via referencing itself to the InitializeMe methods they can do everything they need - as DataBank provides general purpose tools with persistent data, and INITIALIZER provides volatile (hope I use that right, I mean relevant to only main menu) data with some additional functionality that is used only for the main menu.
Now, persistence was ensured not by the persistent class itself, but by this INITIALIZER in Awake like so:
//find by tag or rename upon instantiation as by doing so will result in a "(Clone)" added to its name.
var d = GameObject.FindGameObjectWithTag("DataBank");
if (d == null)
{
//instantiating it
DATA = GameObject.Instantiate<DataBank>(DATA_blueprint);
//intializing the databank itself. The parameters are needed for me,
// but serve as a good example - all of those are dragged from the inspector to the _INITIALIZER_ but will remain in the whole game as long as databank exists.
DATA.LoadDataFromINIT(_baseColor, _baseColor2, _outlineColor,
new MMtoolBundle(DATA));
//to make it persistent.
DontDestroyOnLoad(DATA);
}else
{
//in this case the main menu is loaded from another scene.
//so we only find that loaded object and get its reference, no initialization as it was already setup.
this.DATA = d.GetComponent<DataBank>();
}
where DATA is my persistent DataBank. Note that by default I have NO DataBank object on the scene. DATA_blueprint is the prefab of DataBank dragged by the inspector (as INITIALIZER is not persistent). It could be loaded via AssetDatabase as well but this was a bit more convenient.
it worths mentioning that while DataBank is a MonoBehaviour itself so it can appear in Unity scenes, none of its members are MonoBehaviours so it is possible to harness the power of inheritance. Should one wish to start a coroutine in a non-mono toolkit, it would have to be started with a reference from DataBank itself.
An obvious drawback of this method is that the existence of my persistent GO depends on INITIALIZER, so that one has to be on the first scene. But again, as most games start with a main menu, this shouldn't pose a big issue (talking about single player games).
YET AGAIN I would recommend someone more skilled to correct me in case I lead others astray, but this solution worked for me - got the same and only persistent GO in all my scenes with no other ever created.
Dynamics CRM 2011 on premise. (But this problem exists in many situations away from Dynamics CRM.)
CRM plugins have an entry point:
void IPlugin.Execute (IServiceProvider serviceProvider)
(http://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.iplugin.execute.aspx)
serviceProvider is a reference to the plugin execution context. Anything useful that a plugin does requires accessing serviceProvider, or a member of it.
Some plugins are large and complex and contain several classes. For example, I'm working on a plugin that has a class which is instantiated multiple times. This class needs to use serviceProvider.
One way to get access to serviceProvider from all the classes that need it would be to add a property to all those classes and then to set that property. Or to add properties for the parts of serviceProvider that each class needs. Either of these approaches would result in lots of duplicate code.
Another approach would be to have a global variable in the scope of the thread. However, according to http://msdn.microsoft.com/en-us/library/cc151102.aspx one "should not use global class variables in plug-ins."
So what is the best way to have access to serviceProvider without passing it around everywhere?
P.S. If an example helps, serviceProvider provides access to a logging object. I want almost every class to log. I don't want to pass a reference to the logging object to every class.
That's not quite what the warning in the documentation is getting at. The IServiceProvider isn't a global variable in this context; it's a method parameter, and so each invocation of Execute gets its own provider.
For improved performance, Microsoft Dynamics CRM caches plug-in instances. The plug-in's Execute method should be written to be stateless because the constructor is not called for every invocation of the plug-in. In addition, multiple threads could be running the plug-in at the same time. All per invocation state information is stored in the context. This means that you should not use global class variables in plug-ins [Emphasis mine].
There's nothing wrong with passing objects from the context to helper classes which need them. The warning advises against storing something in a field ("class variable") on the plugin class itself, which may affect a subsequent call to Execute on the same instance, or cause concurrency problems if Execute is called by multiple threads on the same instance simultaneously.
Of course, this "globalness" has to be considered transitively. If you store anything in either the plugin class or in a helper class in any way that multiple calls to Execute can access (using fields on the plugin class or statics on either plugin or helper classes, for example), you leave yourself open to the same problem.
As a separate consideration, I would write the helper classes involved to accept types as specific to their function as possible - down to the level of individual entities - rather than the entire IServiceProvider. It's much easier to test a class which needs only an EntityReference than one which needs to have an entire IServiceProvider and IPluginExecutionContext mocked up.
On global variables vs injecting values required by classes
You're right, this is something that comes up everywhere in object-oriented code. Take a look at these two implementations:
public class CustomEntityFrubber
{
public CustomEntityFrubber(IOrganizationService service, Guid entityIdToFrub)
{
this.service = service;
this.entityId = entityIdToFrub;
}
public void FrubTheEntity()
{
// Do something with service and entityId.
}
private readonly IOrganizationService service;
private readonly Guid entityId;
}
// Initialised by the plugin's Execute method.
public static class GlobalPluginParameters
{
public static IOrganizationService Service
{
get { return service; }
set { service = value; }
}
public static Guid EntityIdToFrub
{
get { return entityId; }
set { entityId = value; }
}
[ThreadStatic]
private static IOrganizationService service;
[ThreadStatic]
private static Guid entityId;
}
public class CustomEntityFrubber
{
public FrubTheEntity()
{
// Do something with the members on GlobalPluginParameters.
}
}
So assume you've implemented something like the second approach, and now you have a bunch of classes using GlobalPluginParameters. Everything is going fine until you discover that one of them is occasionally failing because it needs an instance of IOrganizationService obtained by calling CreateOrganizationService(null), so it accesses CRM as the system user rather than the calling user (who doesn't always have the required privileges).
Fixing the second approach requires you to add another field to your growing list of global variables, remembering to make it ThreadStatic to avoid concurrency problems, then changing the code of CustomEntityFrubber to use the new SystemService property. You have tight coupling between all these classes.
Not only that, all these global variables hang around between plugin invocations. If your code has a bug that somehow bypasses the assignment of GlobalPluginParameters.EntityIdToFrub, suddenly your plugin is inexplicably operating on data that wasn't passed to it by the current call to Execute.
It's also not obvious exactly which of these global variables the CustomEntityFrubber requires, unless you read its code. Multiply that by however many helper classes you have, and maintaining this code starts to become a headache. "Now, does this object need me to have set Guid1 or Guid2 before I call it?" On top of that, the class itself can't be sure that some other code won't go and change the values of global variables it was relying on.
If you used the first approach, you simply pass in a different value to the CustomEntityFrubber constructor, with no further code changes needed. Furthermore, there's no stale data hanging around. The constructor makes it obvious which dependencies the class has, and once it has them, it can be sure that they don't change except in ways they were designed for.
As you say, you shouldn't put a member variable on the plugin since instances are cached and reused between requests by the plugin pipeline.
The approach I take is to create a class that perform the task you need and pass a modified LocalPluginContext (making it a public class) provided by the Developer Toolkit (http://msdn.microsoft.com/en-us/library/hh372957.aspx) on the constructor. Your class then can store the instance for the purposes of executing it's work just in the same way you would with any other piece of code. You are essentially de-coupling from the restrictions imposed by the Plugin framework. This approach also makes it easier to unit test since you only need to provide the execution context to your class rather than mocking the entire plugin pipeline.
It's worth noting that there is a bug in the automatically generated Plugin.cs class in the Developer Toolkit where it doesn't set the ServiceProvider property - At the end of the constructor of the LocalPluginContext add the line:
this.ServiceProvider = serviceProvider;
I have seen some implementations of an IoC approach in Plugins - but IMHO it makes the plugin code way too complex. I'd recommend making your plugins lean and simple to avoid threading/performance issues.
There are multiple things I would worry about in this design request (not that it's bad, just that one should be aware of, and anticipate).
IOrganizationService is not multi-thread safe. I'm assuming that other aspects of the IServiceProvider are not as well.
Testing things at an IServiceProvider level is much more complicated due to the additional properties that have to be mocked
You'd need a method for handle logging if you ever decided to call logic that is currently in your plugin, outside of the plugin (e.g. a command line service).
If you don't want to be passing the object around everywhere, the simple solution is to create a static property on some class that you can set it upon plugin execution, and then access from anywhere.
Of course now you have to handle issue #1 from above, so it'd have to be a singleton manager of some sort, that would probably use the current thread's id to set and retrieve the value for that thread. That way if the plugin is fired twice, you could retrieve the correct context based on your currently executing thread. (Edit Rather than some funky thread id lookup dictionary, #shambulator's ThreadStatic property should work)
For issue #2, I wouldn't be storing the IServiceProvider as is, but split up it's different properties (e.g. IPluginExecutionContext, IOrganizationService, etc)
For issue #3, it might make sense to store an action or a function in your manager rather than the object values themselves. For example, if rather than storing the IPluginExecutionContext, store a func that accepts a string to log and uses the IPlurginExeuctionContext to log. This allows other code to setup it's own logging, without being dependent on executing from within a plugin.
I haven't made any of these plugins myself, but I would treat the IServiceProvider like an I/O device.
Get the data you need from it and convert that data to format that suits your plugin. Use the transformed data to set up the other classes. Get the the output from the other classes and then translate back to terms the IServiceProvider can understand and use.
Your input and output are dependent on the IServiceProvider, but the processing doesn't have to be.
From Eduardo Avaria at http://social.microsoft.com/Forums/en-US/f433fafa-aff7-493d-8ff7-5868c09a9a9b/how-to-avoid-passing-a-context-reference-among-classes
Well, as someone at SO already told you, the global variables restriction is there cause the plugin won't instantiate again if it's called within the same context (the object context and probably other environmental conditions), so any custom global variable would be shared between that instances, but since the context will be the same, there's no problem in assigning it to a global variable if you want to share it between a lot of classes.
Anyways, I'd rather pass the context on the constructors and share it have a little more control over it, but that's just me.
I am running into a design disagreement with a co-worker and would like people's opinion on object constructor design. In brief, which object construction method would you prefer and why?
public class myClass
{
Application m_App;
public myClass(ApplicationObject app)
{
m_App = app;
}
public method DoSomething
{
m_App.Method1();
m_App.Object.Method();
}
}
Or
public class myClass
{
Object m_someObject;
Object2 m_someOtherObject;
public myClass(Object instance, Object2 instance2)
{
m_someObject = instance;
m_someOtherObject = instance2;
}
public method DoSomething
{
m_someObject.Method();
m_someOtherObject.Method();
}
}
The back story is that I ran into what appears to be a fundamentally different view on constructing objects today. Currently, objects are constructed using an Application class which contains all of the current settings for the application (Event log destination, database strings, etc...) So the constructor for every object looks like:
public Object(Application)
Many classes hold the reference to this Application class individually. Inside each class, the values of the application are referenced as needed. E.g.
Application.ConfigurationStrings.String1 or Application.ConfigSettings.EventLog.Destination
Initially I thought you could use both methods. The problem is that in the bottom of the call stack you call the parameterized constructor then, higher up the stack, when the new object expects a reference to the application object to be there, we ran into a lot of null reference errors and saw the design flaw.
My feeling on using an application object to set every class is that it breaks encapsulation of each object and allows the Application class to become a god class which holds information for everything. I run into problems when thinking of the downsides to this method.
I wanted to change the objects constructor to accept only the arguments it needs so that public object(Application) would change to public object(classmember1, classmember2 etc...). I feel currently that this makes it more testable, isolates change, and doesn't obfuscate the necessary parameters to pass.
Currently, another programmer does not see the difference and I am having trouble finding examples or good reasons to change the design, and saying it's my instinct and just goes against the OO principles I know is not a compelling argument. Am I off base in my design thoughts? Does anyone have any points to add in favor of one or the other?
Hell, why not just make one giant class called "Do" and one method on it called "It" and pass the whole universe into the It method?
Do.It(universe)
Keep things as small as possible. Discrete means easier to debug when things inevitably break.
My view is that you give the class the smallest set of "stuff" it needs for it to do its job. The "Application" method is easier upfront but as you've seen already, it will lead to maintainence issues.
I thing Steve McConnel put it very succintly. He states,
"The difference between the
'convenience' philosophy and the
'intellectual manageability'
philosophy boils down to a difference
in emphasis between writing programs
and reading them. Maximizing scope
may indeed make programs easy to
write, but a program in which any
routine can use any variable at any
time is harder to understand than a
program that uses well-factored
routines. In such a program you can't
understand only one routine; you have
to understand all the other routines
with which that routine shares global
data. Such programs are hard to read,
hard to debug, and hard to modify." [McConnell 2004]
I wouldn't go so far as to call the Application object a "god" class; it really seems like a utility class. Is there a reason it isn't a public static class (or, better yet, a set of classes) that the other classes can use at will?