What is a good way to implement pause in a game?
I can come up with these two ideas:
Using FindObjectsOfType<IPausable>()
Having a pause action on the Pauser class and get every object that can be paused subscribe to it
I understand both approaches would work fine, but wouldn't know which one to lean towards to.
Thanks
I think interfaces might be a good solution here.
You could create an IPauseable interface and have any thing you want to pause implement the IPausable interface that way every object you have subscribe to your PauseManager or such can be treat the same.
public interface IPausable{
// interface members
void Pause();
bool isPaused();
void UnPause();
}
Then you can iterate through the list of subscribed objects and doing something like (pseudo code untested to show the idea)
for (int i = 0; i< subScribedComponents.Length; i++)
{
if (subScribedComponents[i] is IPausable)
{
IPausable pauseInterface = subScribedComponents[i] as IPausable;
pauseInterface .Pause();
}
}
The nice thing about doing it this way is that any class that implements IPausable must provide how they will execute those methods themselves and they can all be treat the same way, so whether its a Character or On-Screen timer if it implements the interface you know you've at some point provided a way to pause that particular object.
To directly answer the original question I would vote for the subscriber/publisher method (2) because the first option will have you looping over every object, some not pausable at all, if you go the second route you will be only operating on things you want pausing and not iterating every object in the scene.
Related
I've tried looking around online for a solution to this problem, but I just can't seem to find anything. In my game, I have an Interactor (The Player) and and the Interacted (The target object). What I'm trying to is find a way to check that the object that I've chosen to interact with has a MonoBehaviour that contains the Method "Interacted", and if it does, run it.
This is what my code looks like now, or at least the important bit. OnInteract runs fine when the interaction is selected. The foreach loop will also correctly return each MonoBehaviour in the Transform selected. I can't, however, run a method after getting its MonoBehaviour because it doesn't recognize the method as existing yet. Is there a way for me to check whether or not the method exists and then run it, or should I be taking a different route entirely? Thank You.
So there's a smart way to do this and a dumb/brute-force way.
The smart way is to give all MonoBehaviours you intend to interact with an interface like so:
public interface IInteractable
{
void Interacted();
}
and then implement the interface in all required MonoBehaviours, which forces you to implement the Interacted method:
public class InteractableMonobehaviour12 : MonoBehaviour, IInteractable
Which you can then make use of by checking:
if (interacted.TryGetComponent<IInteractable>(out IInteractable interactable))
interactable.Interacted();
The dumb way is to do exactly as you asked and iterate through all Monobehaviours and then search for the method in them - you can achieve this with C# Reflection, but in this case it is absolutely not required unless you have no control over the classes you want to call Interacted on, so I will spare you the details. If you do want to dive into that, the first code example on this page looks up a types method and executes it without compile-time constraints and checks.
In case you expect multiple components to implement IInteractable on one object, you might want to iterate over the MonoBehaviours anyway if you get a first match, just in case there is a second (I don't think GetComponents works here with interfaces, although that might have changed).
In that case, you can check if the MonoBehaviour implements that interface:
if (component is IInteractable)
((IInteractable)component).Interacted();
Unity has an "interface":
IPointerDownHandler (doco)
You simply implement OnPointerDown ...
public class Whoa:MonoBehaviour,IPointerDownHandler
{
public void OnPointerDown (PointerEventData data)
{ Debug.Log("whoa!"); }
}
and Unity will "magically" call the OnPointerDown in any such MonoBehavior.
You do NOT have to register them, set an event, nor do anything else.
All you do syntactically is add "IPointerDownHandler" and "public void OnPointerDown" to a class, and you can get those messages magically.
(If you're not a Unity dev - it even works if you suddenly add one in the Editor while the game is running!)
How the hell do they do that, and how can I do it?
So, I want to do this:
public interface IGetNews
{
void SomeNews(string s);
}
and then I can add SomeNews to any MonoBehavior.
The alternate solutions are obvious, I want to know specifically how Unity achieve that "magic" behavior.
(BTW: I feel they should not have called these "interfaces", since, it's basically nothing at all like an interface - it's sort of the opposite! You could say they magically made a way to inherit from more than one abstract class, I guess.)
Aside:
if you've not used Unity before, the conventional way to do this - since we don't have access to Unity magic - is just add a UnityEvent to your daemon which will be sending the message in question:
public class BlahDaemon:MonoBehaviour
{
public UnityEvent onBlah;
...
onBlah.Invoke();
Say you have classes Aaa, Bbb, Ccc which want to get the message. Simply connect the Unity event (either by dragging in the editor or in code), example:
public class Aaa:MonoBehaviour
{
void Awake()
{
BlahDaemon b = Object.FindObjectOfType<BlahDaemon>();
b.onBlah.AddListener(OnBlah);
}
public void OnBlah()
{
Debug.Log("almost as good as Unity's");
}
}
You're basically "registering" your call in Awake, you are indeed piggybacking on the magic Unity use - whatever it is. But I want to use the magic directly.
When it comes to XXXUpdate, OnCollisionXXX and other MonoBehaviours, the way Unity registers is not reflection as it has been widely believed but some internal compilation process.
HOW UPDATE IS CALLED
No, Unity doesn’t use System.Reflection to find a magic method every time it needs to call one.
Instead, the first time a MonoBehaviour of a given type is accessed the underlying script is inspected through scripting runtime (either
Mono or IL2CPP) whether it has any magic methods defined and this
information is cached. If a MonoBehaviour has a specific method it is
added to a proper list, for example if a script has Update method
defined it is added to a list of scripts which need to be updated
every frame.
During the game Unity just iterates through these lists and executes methods from it — that simple. Also, this is why it doesn’t matter if
your Update method is public or private.
http://blogs.unity3d.com/2015/12/23/1k-update-calls/
In the case of an interface, I would assume it does a bit more since the interface is required. Else, you would just add the method like any other MonoBehaviour methods.
My assumption (that could be wrong), it uses a basic GetComponents on this GameObject. Then iterate the resulting array and call the method that HAS TO BE implemented since it is from the interface.
You could reproduce the pattern with:
NewsData data;
if(GetNews(out data))
{
IGetNews [] getNews = data.gameObject.GetComponents<IGetNews>();
foreach(IGetNews ign in getNews){ ign.SomeNews(); }
}
GetNews is a method that checks if some news should be sent to the object. You could think of it like Physics.Raycast that assigns values to a RaycastHit. Here it fills a data reference if that object is meant to receive news for any valid reasons.
You can use reflection to get all types in an assembly that implements a specific interface and then instantiate those types and call the methods on those instances through the interface.
var types = this.GetType().Assembly.GetTypes()
.Where(t=>t.GetInterfaces().Contains(typeof(IGetNews)));
foreach (var type in types)
{
var instance = (IGetNews) Activator.CreateInstance(type);
instance.SomeNews("news");
}
The UI-dependent built-in interfaces like IPointerDownHandler, IDragHandler Etc are called by EventsSystem class/script [this is attached on the EventSystem GameObject that is created automatically, when you create UI/Canvas object] and only work on UI Elements [for testing if you turn off or delete the EventSystem GameObject from the scene or even disable EventsSystem script, these interfaces will not be called and all UI elements will stop working (functionality point-of-view, means your register functions will not be called)].
So, these interfaces methods didn't get called as magically on their own. These are called via EventsSystem script.
Read About Event system: CLICK HERE
There are 3 main components that you need to remember for interaction with the UI elements in Unity:
GraphicRaycaster: It is attached to the Canvas object itself. It is responsible for sending the raycasts to UI elements of that canvas and determines if any of them have been hit. if you remove it from the canvas, no interaction can happen with UI elements of that canvas like click, scroll Etc and these interfaces will not also call. [LINK FOR MORE][2]
InputSystemUIInputModule:: this is attached on EventSystem Gameobject is responsible to tell canvases in the whole Unity scene, What to consider as input for the UI and vice versa. Like what will mouse left-click on UI to consider as input to UI elements, etc.
and It calls method link OnPointDown, OnDragStarted Etc interface related. Read More: LINK
EventSystem: it is responsible for processing and handling UI events in a whole Unity scene. It doesn't work independently and required BaseInputModules to work properly and it also maintains elements' status or user interactions. For Details: LINK
Just for understanding, consider it as a story: The EventSystem uses InputSystemUIInputModule to get input from your mouse, keyboard or touch and on the bases of these inputs, the EventSystem calls to does RayCast for whether you have interacted with any element or not (save references of that element in it) if yes then call built-in functions like hover, select, mouse down/up, drag canceled on that element based on life cycle (the mouse/touch pointed elements are stored in EventSystem.current) via InputSystemUIInputModule.
Now, if you want to call any IPointerDownHander method, maybe they do like this internally on click on the element of the UI and vice versa:
IPointerDownHander pointerDownHander = EventSystem.Current.GetComponent<IPointerDownHander>(); //assumption for making an understanding with the interface being cast to object, if that interface is attached to object then that object will be returned and you will be able to call the interface registered method.
if(ipd) ipd.OnPointerDown(var etc)
or below code Copied from Unity UI Package, where you can learn more accurately about this execution
// Invoke OnPointerDown, if present.
var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, eventData, ExecuteEvents.pointerDownHandler);
if (newPressed == null)
newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); //copied from the Unity UI package
I'm currently trying to learn the SOLID design principles along with behavior driven development, but am having quite the hard time getting my head around the Single Responsibility Principle. I've tried to find a good tutorial for c# that uses test driven development, but haven't been able to find anything worthwhile in that vein. Anyway, after spending a few days reading about it, I decided the best way to learn is by experience, so I started creating a small app using those principles best I can.
It's a simple bowling score calculator. I figured the best way to go about it was to work from the simplest part up, so I started at the ball (or throw) level. Right now I have created tests and an interface and class for dealing with ball(throw) scores, which makes sure they aren't invalid, ie. <10 or >0. After implementing this I realized that the ball class is basically just a nullable integer, so maybe I don't even need it... but for now it's there.
Following the ball, I decided the next logical thing to add was a frame interface and class. This is where I have gotten stuck. Here is where I'm at:
namespace BowlingCalc.Frames
{
public interface IFrame : BowlingCalc.Generic.ICheckValid
{
void AddThrow(int? score);
int? GetThrow(int throw_number);
}
}
namespace BowlingCalc.Frames
{
public class Frame : IFrame
{
private List<Balls.IBall> balls;
private Balls.IBall ball;
private int frame_number;
public Frame(Balls.IBall ball, int frame_number)
{
this.ball = ball;
this.frame_number = frame_number;
balls = new List<Balls.IBall>();
check_valid();
}
public void AddThrow(int? score)
{
var current_ball = ball;
current_ball.Score = score;
balls.Add(current_ball);
}
public int? GetThrow(int throw_number)
{
return balls[throw_number].Score;
}
public void check_valid()
{
if (frame_number < 0 || frame_number > 10)
{
throw (new Exception("InvalidFrameNumberException"));
}
}
}
}
The frame uses my previously implemented ball class through dependency injection to add ball scores to the frame. It also implements a way to return the score for any given ball in the frame.
What I want to do, and where I'm stuck, is I want to add a way to make sure the frame score is valid. (For the moment just the simple case of frames 1-9, where the combined score of both balls must be 10 or less. I will move on to the much more complicated frame 10 case later.)
The problem is I have no idea how to implement this in a SOLID way. I was thinking of adding the logic into the class, but that seems to go against the single responsibility principle. Then I thought to add it as a separate interface/class and then call that class on each frame when its score updates. I also thought of creating a separate interface, IValidator or something like that, and implementing that in the Frame class. Unfortunately, I have no idea which, if any, of these is the best/SOLID way of doing things.
So, what would be a good, SOLID way to implement a method that validates the score of a frame?
Note: Any critique of my code is very welcome. I am very excited learn to create better code, and happy to receive any help given.
When I think SRP, I tend to put the emphasis on the Responsibility aspect. The name of the class, in turn, should ideally describe its Responsibility. For some classes this is about what the class is supposed to 'be' (a Frame could be a good example if it lacks behavior and merely represents state), but when you have a behavioral responsibility, the name is about what the class is supposed to 'do'.
Computing scores by itself is a fairly small responsibility, so let's consider something slightly larger and more naturally decomposable. Here is one possible breakdown of a bowling game with simple responsibilities and with suitably paranoid encapsulation (we're all friends here, but nobody wants anybody to cheat by mistake.)
//My job is to keep score; I don't interpret the scores
public interface IScoreKeeper : IScoreReporter
{
void SetScore(int bowlerIndex, int frameIndex, int throwIndex, int score);
}
//My job is to report scores to those who want to know the score, but shouldn't be allowed to change it
public interface IScoreReporter
{
int? GetScore(int bowlerIndex, int frameIndex, int throwIndex);
}
//My job is to play the game when told that it's my turn
public interface IBowler
{
//I'm given access to the ScoreReporter at some point, so I can use that to strategize
//(more realisically, to either gloat or despair as applicable)
//Throw one ball in the lane, however I choose to do so
void Bowl(IBowlingLane lane);
}
//My job is to keep track of the pins and provide score feedback when they are knocked down
//I can be reset to allow bowling to continue
public interface IBowlingLane
{
int? GetLastScore();
void ResetLane();
}
//My job is to coordinate a game of bowling with multiple players
//I tell the Bowlers to Bowl, retrieve scores from the BowlingLane and keep
//the scores with the ScoreKeeper.
public interface IBowlingGameCoordinator
{
//In reality, I would probably have other service dependencies, like a way to send feedback to a monitor
//Basically anything that gets too complicated and can be encapsulated, I offload to some other service to deal with it
//I'm lazy, so all I want to do is tell everybody else what to do.
void PlayGame(IScoreKeeper gameScore, IEnumerable<IBowler> bowlers, IBowlingLane lane);
}
Note that if you wanted to use this model to simply compute scores (without playing a real game), you can have a stub Bowler (who does nothing) and a MockBowlingLane, who produces a series of score values. The BowlingGameCoordinator takes care of the current bowler, frame and throw, so the scores get accumulated.
What is the purpose of ICheckValid interface? Do you call check_valid elsewhere? In my opinion, since the frame_number seems to be in fact a read-only property of a Frame, why it would be wrong to verify its consistency right in the constructor without any additional interfaces for that? (Constructors are supposed to produce consistent objects and are thus free to validate incoming parameters however they like.)
However, rather than to ask how to properly validate this field, it might be better to ask why indeed you need the frame_number property in the Frame? It seems like this is an index of this item in some array - you may just use the index, why store it in the Frame? You may want to write some if/else logic later, such as:
if (frame_number == 10) {
// some rules
} else {
// other rules
}
However, this is unlikely a SOLID approach as you would probably end up writing this if/else statements in many parts of the Frame. Rather, you may create a base class FrameBase, define much of the logics there plus some abstract methods to be implemented in OrdinaryFrame and TenthFrame, where you would define different rules. This would enable you to avoid frame_number altogether -- you would just create nine OrdinaryFrames and one TenthFrame.
As for critique: your code seems to abstract balls and frames, but ignores 'throws', or 'rolls' for some reason. Consider a need to add trajectory information of each roll, you would need to change the IFrame interface, adding something like void SetThrowTrajectory(int throwNumber, IThrowTrajectory trajectory). However, if you abstract throws away in an e.g. IBallRoll, the trajectory-related functionality would easily fit there (as well as some Boolean computed properties, e.g. IsStrike, IsSpare).
I have a large abstract class that handles weapons in my game. Combat cycles through a list of basic functions:
OnBeforeSwing
OnSwing
OnHit || OnMiss
What I have in mind is moving all combat damage-related calculations to another folder that handles just that. Combat damage-related calculations.
I was wondering if it would be correct to do so by making the OnHit method an extension one, or what would be the best approach to accomplish this.
Also. Periodically there are portions of the OnHit code that are modified, the hit damage formula is large because it takes into account a lot of conditions like resistances, transformation spells, item bonuses, special properties and other, similar, game elements.
This ends with a 500 line OnHit function, which kind of horrifies me. Even with region directives it's pretty hard to go through it without getting lost in the maze or even distracting yourself.
If I were to extend weapons with this function instead of just having the OnHit function, I could try to separate the different portions of the attack into other functions.
Then again, maybe I could to that by calling something like CombatSystem.HandleWeaponHit from the OnHit in the weapon class, and not use extension methods. It might be more appropriate.
Basically my question is if leaving it like this is really the best solution, or if I could (should?) move this part of the code into an extension method or a separate helper class that handles the damage model, and whether I should try and split the function into smaller "task" functions to improve readability.
I'm going to go out on a limb and suggest that your engine may not be abstracted enough. Mind you, I'm suggesting this without knowing anything else about your system aside from what you've told me in the OP.
In similar systems that I've designed, there were Actions and Effects. These were base classes. Each specific action (a machine gun attack, a specific spell, and so on) was a class derived from Action. Actions had an list of one or more specific effects that could be applied to Targets. This was achieved using Dependency Injection.
The combat engine didn't do all the math itself. Essentially, it asked the Target to calculate its defense rating, then cycled through all the active Actions and asked them to determine if any of its Effects applied to the Target. If they applied, it asked the Action to apply its relevant Effects to the Target.
Thus, the combat engine is small, and each Effect is very small, and easy to maintain.
If your system is one huge monolithic structure, you might consider a similar architecture.
OnHit should be an event handler, for starters. Any object that is hit should raise a Hit event, and then you can have one or more event handlers associated with that event.
If you cannot split up your current OnHit function into multiple event handlers, you can split it up into a single event handler but refactor it into multiple smaller methods that each perform a specific test or a specific calculation. It will make your code much more readable and maintainable.
IMHO Mike Hofer gives the leads.
The real point is not whether it's a matter of an extension method or not. The real point is that speaking of a single (extension or regular) method is unconceivable for such a complicated bunch of calculations.
Before thinking about the best implementation, you obviously need to rethink the whole thing to identify the best possible dispatch of responsibilities on objects. Each piece of elemental calculation must be done by the object it applies to. Always keep in mind the GRASP design patterns, especially Information Expert, Low Coupling and High Cohesion.
In general, each method in your project should always be a few lines of code long, no more. For each piece of calculation, think of which are all the classes on which this calculation is applicable. Then make this calculation a method of the common base class of them.
If there is no common base class, create a new interface, and make all these classes implement this interface. The interface might have methods or not : it can be used as a simple marker to identify the mentioned classes and make them have something in common.
Then you can build an elemental extension method like in this fake example :
public interface IExploding { int ExplosionRadius { get; } }
public class Grenade : IExploding { public int ExplosionRadius { get { return 30; } } ... }
public class StinkBomb : IExploding { public int ExplosionRadius { get { return 10; } } ... }
public static class Extensions
{
public static int Damages(this IExploding explosingObject)
{
return explosingObject.ExplosionRadius*100;
}
}
This sample is totally cheesy but simply aims to give leads to re-engineer your system in a more abstracted and maintenable way.
Hope this will help you !
I have two classes, Human and Monster.
both have a Property called MoveBehavior
Human has HumanMoveBehavior, and Monster has MonsterMoveBehavior
I want the HumanMoveBehavior to move AWAY from Monsters, and MonsterMoveBehavior to move TOWARD Humans.
The problem I'm having is where should I put my code to move?
In the Human/Monster class?
Using this approach, I had a Move() Method, which takes a List of all entities in game, decides whether it's a Monster or Human using a method called GetListOfOpponents(List allsprites) and then runs GetNearestOpponent(List opponents);
But this looks really messy.
Should I have a SpriteController that decides where the Sprites move? I'm unsure where I need to put this code :(
Thanks!
You could think of a AIManager that just says:
foreach(GameObject go in m_myObjects) // m_myObjects is a list of all objects that require updating
{
go.Update(); // standard GameObject function
}
After that, each class should take care of its own piece of code. So updating works in the class itself.
So Human says:
// just a class which is a gameObject and also has moving behaviour
// do the same with monster
public class Human : GameObject, IMoveBehaviour
{
public override Update()
{
GoMove();
}
public void GoMove()
{
// human specific logic here
}
}
// This interface describes that some movement
// will happen with the implementing class
public interface IMoveBehaviour
{
void GoMove();
}
With using an interface, you can make the specific language part of the class and you don't have need to ALSO create some class that will handle that for you. Of course it is possible. But in real life, the human/monster is the one that is moving, not some object he is carrying.
UPDATE
Answer to the comment. Because there is an AIManager, or even a complete GameObjectManager would be nice to maintain all GameObjects, you could ask the AIManager for the placed where you could not go.
Because pathfinding is most of the time done by use of some navigation mesh or a specified grid, the GameObjectManager can return the specific Grid with all navigable points on it. You should for certain not define all positions in every monster. Because most of the time, the monster does not exactly know where everyone is (in real life). So knowing where not to go is indeed good, but knowing where everyone is, will give your AI too much advantage as well.
So think of returning a grid with the points where to go and where not to, instead of maintaining such things inside the monster/human. Always check where you should leave what, by thinking about what would be the thing in real life.
The way Valve handled this for entities in Half Life 2, is one of the better ways, I think. Instead of giving each AI its own separate Move methods and calling those, it simply called the Think() method and let the entity decide what it needed to do.
I'd go with what Marnix says and implement an AIManager that loops through each active AI in the game world, calling the Think() method of each. I would not recommended interfacing your Human class with an "IMoveBehavior" simply because it would be better to abstract that into a "WorldEntity" abstract class.
You might have invisible entities that control things like autosaves, triggers, lighting, etc, but some will have a position in the world. These are the ones who will have a vector identifying their position. Have the AI's Think() method call its own move() method, but keep it private. The only one who needs to think about moving is the AI itself.
If you want to encourage the AI to move outside of the Think) method, I would suggest some kind of imperative, such as a Goal-Oriented Action Planning (GOAP) system. Jeff Orkin wrote about this fantastic concept, and it was used in games such as F.E.A.R. and Fallout 3. It might be a bit overkill for your application, but I thought it was interesting.
http://web.media.mit.edu/~jorkin/goap.html