Is it a good practice to create a class between my own scripts and mono behavior? - unity3d

So, I have bound the CombatController to an object called "godObject". In the Start() method, I call init() functions on other classes. I did this so I can control the order in which objects are initialized since, for example, the character controller relies on the grid controller being initialized.
Quick diagram:
-------------------- calls
| CombatController | ----------> CameraController.init();
-------------------- |
| ---> GridController.init();
|
| ---> CharacterController.init();
So, now I have a slight problem. I have multiple properties that I need in every controller. At the moment, I have bound everything to the combat controller itself. That means that, in every controller, I have to get an instance of the CombatController via GameObject.Find("godObject).GetComponent<CombatController>(). To be honest, I don't think this is good design.
My idea now was to create a BaseCombatController that extends MonoBehavior, and then have all other classes like GridController, CharacterController etc. extend the BaseCombatController. It might look like this:
public class BaseCombatController : MonoBehaviour
{
public GameObject activePlayer;
public void setActivePlayer(GameObject player) {
this.activePlayer = player;
}
... more stuff to come ...
}
This way, I could access activePlayer everywhere without the need to create a new instance of the CombatController. However, I'm not sure if this doesn't have possible side effects.
So, lots of text for a simple question, is that safe to do?

I use inheritance in Unity all the time. The trick, like you have in the question, is to allow your base class to inherit from monobehavior. For Example:
public class Base Item : Monobehavior
{
public string ItemName;
public int Price;
public virtual void PickUp(){//pickup logic}
//Additional functions. Update etc. Make them virtual.
}
This class sets up what an item should do. Then in a derived class you can change and extend this behavior.
public class Coin : BaseItem
{
//properties set in the inspector
public override void PickUp(){//override pickup logic}
}
I have used this design pattern a lot over the past year, and am currently using it in a retail product. I would say go for it! Unity seems to favor components over inheritance, but you could easily use them in conjunction with each other.
Hope this helps!

As far as I can see this should be safe. If you look into Unity intern or even Microsoft scripts they all extend/inhert (from) each other.
Another thing you could try would be the use of interfaces, here is the Unity Documentation to them: https://unity3d.com/learn/tutorials/topics/scripting/interfaces if you want to check it out.

You are right that GameObject.Find is pure code smell.
You can do it via the inheritance tree (as discussed earlier) or even better via interfaces (as mentioned by Assasin Bot), or (I am surprised no one mentioned it earlier) via static fields (aka the Singleton pattern).
One thing to add from experience - having to have Inits() called in a specific order is a yellow flag for your design - I've been there myself and found myself drowned by init order management.
As a general advice: Unity gives you two usefull callbacks - Awake() and Start(). If you find yourself needing Init() you are probably not using those two as they were designed.
All the Awakes() are guaranteed (for acvie objects) to run before first Start(), so do all the internal object initialisation in Awake(), and binding to external objects on Start(). If you find yourself needing finer control - you should probably simplify the design a bit.
As a rule of thumb: all objects should have their internal state (getcomponents<>, list inits etc) in order by the end of Awake(), but they shold not make any calls depending on other objects being ready before Start(). Splitting it this way usually helps a lot

Related

Is it possible to implement a module that is not a WPF module (a standard class library, no screens)?

I am developing a modular WPF application with Prism in .Net Core 5.0 (using MVVM, DryIoc) and I would like to have a module that is not a WPF module, i.e., a module with functionality that can be used by any other module. I don't want any project reference, because I want to keep the loosely coupled idea of the modules.
My first question is: is it conceptually correct? Or is it mandatory that a module has a screen? I guess it should be ok.
The second and more important (for me) is, what would be the best way to create the instance?
This is the project (I know I should review the names in this project):
HotfixSearcher is the main class, the one I need to get instantiated. In this class, for example, I subscribe to some events.
And this is the class that implements the IModule interface (the module class):
namespace SearchHotfix.Library
{
public class HotfixSearcherModule : IModule
{
public HotfixSearcherModule()
{
}
public void OnInitialized(IContainerProvider containerProvider)
{
//Create Searcher instance
var searcher = containerProvider.Resolve<IHotfixSearcher>();
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IHotfixSearcher, HotfixSearcher>();
}
}
}
That is the only way I found to get the class instantiated, but I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
For modules that have screens, the instances get created when navigating to them using the RequestNavigate method:
_regionManager.RequestNavigate(RegionNames.ContentRegion, "ContentView");
But since this is only a library with no screens, I can't find any other way to get this instantiated.
According to Prism documentation, subscribing to an event shoud be enough but I tried doing that from within my main class HotfixSearcher but it does not work (breakpoints on constructor or on the event handler of the event to which I subscribe are never hit).
When I do this way, instead, the instance is created, I hit the constructor breakpoint, and obviously the instance is subscribed to the event since it is done in the constructor.
To sum up, is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
Thanks in advance!
Or is it mandatory that a module has a screen?
No, of course not, modules have nothing to do with views or view models. They are just a set of registrations with the container.
what would be the best way to create the instance?
Let the container do the work. Normally, you have (at least) one assembly that only contains public interfaces (and the associated enums), but no modules. You reference that from the module and register the module's implementations of the relevant interfaces withing the module's Initialize method. Some other module (or the main app) can then have classes that get the interfaces as constructor parameters, and the container will resolve (i.e. create) the concrete types registered in the module, although they are internal or even private and completely unknown outside the module.
This is as loose a coupling as it gets if you don't want to sacrifice strong typing.
is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
You can skip the var searcher = part :-) But if the HotfixSearcher is never injected anywhere, it won't be created unless you do it yourself. OnInitialized is the perfect spot for this, because it runs after all modules had their chance to RegisterTypes so all dependencies should be registered.
If HotfixSearcher is not meant to be injected, you can also drop IHotfixSearcher and resolve HotfixSearcher directly:
public void OnInitialized(IContainerProvider containerProvider)
{
containerProvider.Resolve<HotfixSearcher>();
}
I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
It is used, I suppose, although not through calling one of its methods. It's used by sending it an event. That's just fine. Think of it like Task.Run - it's fine for the task to exist in seeming isolation, too.

Advice on Flexible Pickup System

First off, this is my first time posting here and I am new to coding so please for give me for all things. :)
I am trying to make a flexible pickup system for a game in Unity using C#. I would like to be able to pick a Pickup Type from a drop down have the code then direct which variable it updates with the minimal number of values for me or future designers to have to adjust.
For Example:
In the game you have a health pickup and a stamina pickup. I place the same HealthSystemPickup.cs on both game objects. In the inspector I choose if it is a health or stamina pickup type and then adjust the increase or decrease values. The code will then tell it to either update the health or stamina based on the pickup type selected. So on and so on for any future pickup types.
What I Have so far:
I have a script that defines the PickupTypes via public enums.
I have another script that is the Pickup itself which allows you to pick from that list of enums and set an increase and decrease value upon a OnTiggerEnter event.
Simple enough and works as long as I am calling specific methods from my health system script, but not based on the PickupType... and that is what I am stuck on. I am not sure how to direct what methods I am calling based on the PickupType it is.
I'd love advice on where to investigate or direction people have taken to do something similar.
any help would be great!
thank you.
This sounds like a good candidate for using polymorphism. You can define an interface or an abstract superclass that has all the methods your other scripts would interact with, and separate classes (rather than a single class with a type enum) for the health and stamina types. Something like:
public abstract class Pickup : MonoBehaviour
{
public int amount = 10;
public abstract void PickUp(Player player);
}
public class HealthPickup : Pickup
{
public override void PickUp(Player player)
{
player.Health += amount;
}
}
public class StaminaPickup
{
public override void PickUp(Player player)
{
player.Stamina += amount;
}
}
When you need to deal with pickups in other classes, you never address HealthPickup or StaminaPickup directly, you just refer to them as instances of Pickup.

Excluding member functions and inheritance, what are some of the most common programming patterns for adding functionality to a class?

There're likely no more than 2-4 widely used approaches to this problem.
I have a situation in which there's a common class I use all over the place, and (on occasion) I'd like to give it special abilities. For arguments sake, let's say that type checking is not a requirement.
What are some means of giving functionality to a class without it being simply inheritance or member functions?
One way I've seen is the "decorator" pattern in which a sort of mutator wraps around the class, modifies it a bit, and spits out a version of it with more functions.
Another one I've read about but never used is for gaming. It has something to do with entities and power-ups/augments. I'm not sure about the specifics, but I think they have a list of them.
???
I don't need specific code of a specific language so much as a general gist and some keywords. I can implement from there.
So as far as I understand, you're looking to extend an interface to allow client-specific implementations that may require additional functionality, and you want to do so in a way that doesn't clutter up the base class.
As you mentioned, for simple systems, the standard way is to use the Adaptor pattern: subclass the "special abilities", then call that particular subclass when you need it. This is definitely the best choice if the extent of the special abilities you'll need to add is known and reasonably small, i.e. you generally only use the base class, but for three-to-five places where additional functionality is needed.
But I can see why you'd want some other possible options, because rarely do we know upfront the full extent of the additional functionality that will be required of the subclasses (i.e. when implementing a Connection API or a Component Class, each of which could be extended almost without bound). Depending on how complex the client-specific implementations are, how much additional functionality is needed and how much it varies between the implementations, this could be solved in a variety of ways:
Decorator Pattern as you mentioned (useful in the case where the special entities are only ever expanding the pre-existing methods of the base class, without adding brand new ones)
class MyClass{};
DecoratedClass = decorate(MyClass);
A combined AbstractFactory/Adaptor builder for the subclasses (useful for cases where there are groupings of functionality in the subclasses that may differ in their implementations)
interface Button {
void paint();
}
interface GUIFactory {
Button createButton();
}
class WinFactory implements GUIFactory {
public Button createButton() {
return new WinButton();
}
}
class OSXFactory implements GUIFactory {
public Button createButton() {
return new OSXButton();
}
}
class WinButton implements Button {
public void paint() {
System.out.println("I'm a WinButton");
}
}
class OSXButton implements Button {
public void paint() {
System.out.println("I'm an OSXButton");
}
}
class Application {
public Application(GUIFactory factory) {
Button button = factory.createButton();
button.paint();
}
}
public class ApplicationRunner {
public static void main(String[] args) {
new Application(createOsSpecificFactory());
}
public static GUIFactory createOsSpecificFactory() {
int sys = readFromConfigFile("OS_TYPE");
if (sys == 0) return new WinFactory();
else return new OSXFactory();
}
}
The Strategy pattern could also work, depending on the use case. But that would be a heavier lift with the preexisting base class that you don't want to change, and depending on if it is a strategy that is changing between those subclasses. The Visitor Pattern could also fit, but would have the same problem and involve a major change to the architecture around the base class.
class MyClass{
public sort() { Globals.getSortStrategy()() }
};
Finally, if the "special abilities" needed are enough (or could eventually be enough) to justify a whole new interface, this may be a good time for the use of the Extension Objects Pattern. Though it does make your clients or subclasses far more complex, as they have to manage a lot more: checking that the specific extension object and it's required methods exist, etc.
class MyClass{
public addExtension(addMe) {
addMe.initialize(this);
}
public getExtension(getMe);
};
(new MyClass()).getExtension("wooper").doWoop();
With all that being said, keep it as simple as possible, sometimes you just have to write the specific subclasses or a few adaptors and you're done, especially with a preexisting class in use in many other places. You also have to ask how much you want to leave the class open for further extension. It might be worthwhile to keep the tech debt low with an abstract factory, so less changes need to be made when you add more functionality down the road. Or maybe what you really want is to lock the class down to prevent further extension, for the sake of understand-ability and simplicity. You have to examine your use case, future plans, and existing architecture to decide on the path forward. More than likely, there are lots of right answers and only a couple very wrong ones, so weigh the options, pick one that feels right, then implement and push code.
As far as I've gotten, adding functions to a class is a bit of a no-op. There are ways, but it seems to always get ugly because the class is meant to be itself and nothing else ever.
What has been more approachable is to add references to functions to an object or map.

Entity Framework Inheritance and Logic

I've been creating a prototype for a modern MUD engine. A MUD is a simple form of simulation and provide a good method in which to test a concept I'm working on. This has led me to a couple of places in my code where things, are a bit unclear, and the design is coming into question (probably due to its being flawed). I'm using model first (I may need to change this) and I've designed a top down architecture of game objects. I may be doing this completely wrong.
What I've done is create a MUDObject entity. This entity is effectively a base for all of my other logical constructs, such as characters, their items, race, etc. I've also created a set of three meta classes which are used for logical purposes as well Attributes, Events, and Flags. They are fairly straightforward, and are all inherited from MUDObject.
The MUDObject class is designed to provide default data behavior for all of the objects, this includes deletion of dead objects. The automatically clearing of floors. etc. This is also designed to facilitate this logic virtually if needed. For example, checking a room to see if an effect has ended and deleting the the effect (remove the flag).
public partial class MUDObject
{
public virtual void Update()
{
if (this.LifeTime.Value.CompareTo(DateTime.Now) > 0)
{
using (var context = new ReduxDataContext())
{
context.MUDObjects.DeleteObject(this);
}
}
}
public virtual void Pause()
{
}
public virtual void Resume()
{
}
public virtual void Stop()
{
}
}
I've also got a class World, it is derived from MUDObject and contains the areas and room (which in turn contain the games objects) and handles the timer for the operation to run the updates. (probably going to be moved, put here as if it works would limit it to only the objects in-world at the time.)
public partial class World
{
private Timer ticker;
public void Start()
{
this.ticker = new Timer(3000.0);
this.ticker.Elapsed += ticker_Elapsed;
this.ticker.Start();
}
private void ticker_Elapsed(object sender, ElapsedEventArgs e)
{
this.Update();
}
public override void Update()
{
this.CurrentTime += 3;
// update contents
base.Update();
}
public override void Pause()
{
this.ticker.Enabled = false;
// update contents
base.Pause();
}
public override void Resume()
{
this.ticker.Enabled = true;
// update contents
this.Resume();
}
public override void Stop()
{
this.ticker.Stop();
// update contents
base.Stop();
}
}
I'm curious of two things.
Is there a way to recode the context so that it has separate
ObjectSets for each type derived from MUDObject?
i.e. context.MUDObjects.Flags or context.Flags
If not how can I query a child type specifically?
Does the Update/Pause/Resume/Stop architecture I'm using work
properly when placed into the EF entities directly? given than it's for
data purposes only?
Will locking be an issue?
Does the partial class automatically commit changes when they are made?
Would I be better off using a flat repository and doing this in the game engine directly?
1) Is there a way to recode the context so that it has separate ObjectSets for each type derived from MUDObject?
Yes, there is. If you decide that you want to define a base class for all your entities it is common to have an abstract base class that is not part of the entity framework model. The model only contains the derived types and the context contains DbSets of derived types (if it is a DbContext) like
public DbSet<Flag> Flags { get; set; }
If appropriate you can implement inheritance between classes, but that would be to express polymorphism, not to implement common persistence-related behaviour.
2) Does the Update/Pause/Resume/Stop architecture I'm using work properly when placed into the EF entities directly?
No. Entities are not supposed to know anything about persistence. The context is responsible for creating them, tracking their changes and updating/deleting them. I think that also answers your question about automatically committing changes: no.
Elaboration:
I think here it's good to bring up the single responsibility principle. A general pattern would be to
let a context populate objects from a store
let the object act according to their responsibilities (the simulation)
let a context store their state whenever necessary
I think Pause/Resume/Stop could be responsibilities of MUD objects. Update is an altogether different kind of action and responsibility.
Now I have to speculate, but take your World class. You should be able to express its responsibility in a short phrase, maybe something like "harbour other objects" or "define boundaries". I don't think it should do the timing. I think the timing should be the responsibility of some core utility which signals that a time interval has elapsed. Other objects know how to respond to that (e.g. do some state change, or, the context or repository, save changes).
Well, this is only an example of how to think about it, probably far from correct.
One other thing is that I think saving changes should be done not nearly as often as state changes of the objects that carry out the simulation. It would probably slow down the process dramatically. Maybe it should be done in longer intervals or by a user action.
First thing to say, if you are using EF 4.1 (as it is tagged) you should really consider going to version 5.0 (you will need to make a .NET 4.5 project for this)
With several improvements on performance, you can benefit from other features also. The code i will show you will work for 5.0 (i dont know if it will work for 4.1 version)
Now, let's go to you several questions:
Is there a way to recode the context so that it has separate
ObjectSets for each type derived from MUDObject? If not how can I
query a child type specifically?
i.e. context.MUDObjects.Flags or context.Flags
Yes, you can. But to call is a little different, you will not have Context.Worlds you will only have the base class to be called this way, if you want to get the set of Worlds (that inherit from MUDObject, you will call:
var worlds = context.MUDObjects.OfType<World>();
Or you can do in direct way by using generics:
var worlds = context.Set<World>();
If you define you inheritance the right way, you should have an abstract class called MUDObjects and all others should iherit from that class. EF can work perfectly with this, you just need to make it right.
Does the Update/Pause/Resume/Stop architecture I'm using work properly
when placed into the EF entities directly? given than it's for data
purposes only?
In this case i think you should consider using a Design Pattern called Strategy Pattern, do some research, it will fit your objects.
Will locking be an issue?
Depends on how you develop the system....
Does the partial class automatically commit changes when they are
made?
Did not understand that question.... Partial classes are just like regular classes, thay are just in different files, but when compiled (or event at Design-Time, because of the vshost.exe) they are in fact just one.
Would I be better off using a flat repository and doing this in the
game engine directly?
Hard to answer, it all depends on the requirements of the game, deploy strategy....

What is the point declaring variables at the end of class?

I saw multiple examples in MSDN that uses to declare the internal fields at the end of the class. What is the point?
I find this a little embarrassing, because each time Visual Studio adds a method it adds it to the end of the class, so there is need every time to move it...
class A
{
public A(){}
// Methods, Properties, etc ...
private string name;
}
class A
{
private string name;
public A(){}
// Methods, Properties, etc ...
}
In C++, it makes sense to put the public interface of the class at the top, so that any user of the class can open up your header file and quickly see what's available. By implication, protected and private members are put at the bottom.
In C# and Java, where interface and implementation are completely intertwined, people would probably not open your class's source code to see what's available. Instead they would rely on code completion or generated documentation. In that case, the ordering of the class members is irrelevant.
If it's obvious the variable has been declared, and the code is by way of an example, then arguably this gets you to the bit being demonstrated quicker - that's all I can think of.
Add-ins like ReSharper will allow you to standardise and automatically apply this layout at the touch of a key combination, by the way, if it is what you want.
Many programmers strive for self-documenting code that helps clients to understand it. In C++ class declaration, they would go from most important (i.e. what is probably most frequently inspected) to least important:
class Class {
public:
// First what interest all clients.
static Class FromFoobar(float foobar); // Named constructors in client code
// often document best
Class(); // "Unnamed" constructors.
/* public methods */
protected:
// This is only of interest to those who specialize
// your class.
private:
// Of interest to your class.
};
Building on that, if you use Qt, the following ordering might be interesting:
class SomeQtClass : public QObject {
public:
signals: // what clients can couple on
public slots: // what clients can couple to
protected:
protected slots:
};
Then the same down for protected and private slots. There is no specific reason why I prefer signals over slots; maybe because signals are always public, but I guess the ordering of them would depend on the situation, anyhow, I keep it consistent.
Another bit I like is to use the access-specifiers to visually seperate behaviour from data (following the importance ordering, behaviour first, data last, because behaviour is the top-interest for the class implementor):
class Class {
private:
void foobar() ;
private:
float frob_;
int glob_;
};
Keeping the last rule helps to prevent visual scattering of class components (we all know how some legacy classes look like over time, when variables and functions are mixed up, not?).
I don't think there is any valid reason for this. If you run Code Analysis on a class declared like this you'll get an error as private fields should be declared on top of classes (and below constants).