best practice for changing GameObject behaviour between parents? - c#

I have a game object that i need to move around in the scene.
Every time the game object is under a different parent it should behave differently in just one little aspect of its existance.
For example, let say i have a dog, when it is under a kid parent, the dog should play.
If the dog game object is move to be under the adult parent, it should bark. etc...
My solution at first was to use if-else and check under which parent the dog is being used.
And by knowing the parent i can invoke the correct method of dog action.
But that approach is very ugly, and not very scalable.
I would like to maybe do something more polymorphic, and maybe create multiple dog classes, one for barking, one for playing, etc, and than somehow instantiate a new game object with different script every time the owner of the dog changes.
What is the best practice for such a thing?
No need to mention that i have many game objects that are switching their respective parents so i need a systematic solution.
Thank yous

Related

Trying to find an approach for an item crafting system for a Unity game

EDIT: I found a solution that works without needing to overhaul much of what I've done... and made myself feel like a fool, because it was at the top of my notes from when I started this project a week ago.
A dictionary containing names and IDs of items will exist, the game will add the ID of any given item to the mixing pot list, sort them in numerical order, and compare the result to a recipe dictionary.
I'll leave the original question here in case anyone else happens to have my weirdly specific problem.
The basic problem I aim to solve is a system in which the player can add ingredients to a mixing pot, click a button, and the game will read the list of ingredients and return a potion (or any other item, but I'm speaking on potions for simplicity's sake). The recipes for potions can get somewhat specific, and potions may need multiple of specific ingredients. The player might also add ingredients in an arbitrary order, and I want to account for that.
My original plan, when I started this project, was for each item to be loaded from a JSON or something, where they'd have a formID based on their list position. This formID would be taken for all the items thrown in the mixing pot, sorted, then checked against a dictionary of all craftable items to find what potion was made.
The problem I've run into, however, is that the detail and scale of my item system has grown to the point where each item is its own programmed object interfacing with a list of traits, each of which is their own programmed object with an interface for determining their parent items' function. For a clearer explanation, the structure I've gone with derives from this post: https://gamedev.stackexchange.com/questions/147873/creating-a-robust-item-system
Constructing things in this way allows for me to have an immense amount of flexibility in what any given item can do, what can be done with it, and what it can interact with. However, I can't be certain of the exact number of components or properties any given item should have, which makes building a JSON a bit complicated. I'm willing to do it, but I'm trying to poke around for options.
The way I see it, I could either restructure my items from the ground up to load from some sort of database file (which I feel would take away from some of the control I have over the unique function, interactivity, and variety of each given item) for the FormID method, or I could do something else.
The only other ideas I've had so far are adding some sort of FormID manually (which seems like a pain to keep track of), or taking the item name strings from the list of items in the pot, sorting them alphabetically, concatenating them together, and doing a dictionary sweep that way, but I feel like that would be far from ideal. I'm somewhat new to this particular aspect, but I'll do what I can to answer questions.
I recommend the database approach.
At first glance I see it consisting of 3 Tables.
Potion table this is where you would store any intrinsic information that all potions share like a Name, you can also store any traits here in one column using JSON.
Ingredients table this is where you would store all possible ingredients.
Potion_Ingredients table this is a relational table that links any number of ingredients to any number of potions.
Example of a potion in the DB.
ID| NAME |TYPE | EFFECT
1 | Regen Potion |Regen | {"HP":"50","RegenPerTick":".5"}
The Name will be used for display purposes.
The Type will be used by the Consumer to determine how to handle the Potion.
The Effect will be used in context with the Type to act in a general way.
Using JSON in this situation would allow you to store any number of effects per potion.
This post is all over the place, to the point that I can't really tell what you're asking about. You start out talking about crafting and items, so I thought it would be about how you check a list of ingredients against a list of recipes, but then you pivot to traits and deserializing from JSON, but then you provide an example of a healing potion and I can't tell why, then you seem to go back to deserializing and finally back to ingredient matching.
I think it would help you a lot to outline what you're trying to do with a sequence diagram or similar and try to break down your approach into manageable parts. The ingredient matching doesn't have anything to do with deserializing, which in turn shouldn't really have much to do with your possible potion types.
In general, I would urge you to respect encapsulation. When you say:
each of which is their own programmed object with an interface for determining their parent items' function.
that's a big screaming red flag to me. Why would a potion know about a sword or a scythe or a maul or a mace or a halberd etc. etc. A potion just knows it gives +5 to attack for 40 seconds. It's up to the user to know how to use it. Using an attack potion on bracers or boots doesn't do anything because they don't implement the IAttack interface, etc., but because it's an item it still implemented the IItem interface which means it can ApplyPotion(). The potion still gets used, it just gets lost (fizzles).
Traits or modifiers, like a fire opal instead of a regular opal, etc., are just bonuses. They should still count as their base ingredients (opal) for the purposes of ingredient checking, but when you make the potion you aggregate the bonuses on all ingredients and apply them to the finished product. You can have it such that multiple bonuses don't stack, or they do, or they do to an extent, or there could be tiers of bonuses like Fire I, Fire II, etc.
For crafting, you could make a string or int be the key in a dictionary, and you can build that key by assigning each ingredient class its own location, so ones indicates the number of feathers, tens is opals, hundreds is scales, thousands is gold, etc., such that a spell of 1201 would be one piece of gold, two scales, and one feather.
Maybe instead of a dictionary that returns subclasses of Potion you could use a switch statement in a PotionFactory that just configures a single base Potion class. If it doesn't find a match the default case could return null and you fail to build, or you could destroy all the ingredients, etc.
Deserializing is relatively straightforward when you use something like XML if you just make each component responsible for deserializing itself. Load the XML file, and when you get to a Potion tag you instantiate a new potion then hand the XML reference to the Potion. The Potion knows what fields it has and which are required and which are optional. Any classes that Potion needs also deserialize themselves, so each time you hit a Bonus tag you'd instantiate a Bonus, add it to the Potion bonuses, and hand the XML reference off to the Bonus to deserialize whatever it needed. This is almost like a recursive function - it goes as deep as it needs to go.
Anyways this is kind a rambling answer to a rambling question, but hopefully it helps point you in some better directions.

How can I realise different actions (e.g. change scenery, interact with npc, pick up items) using the input system of Unity?

I am using the (new) input system of Unity and have the problem to realise an interaction with different objects. I am still quite new to Unity and hope to find some help.
I have created an event (OnInteract) that listens to whether e has been pressed.
Next I created an object with a collider into which my player can run. Whenever the player meets a certain collider, something should happen. In my case I want to change the scene. However, on my initial scene there are two doors that the player can open by pressing e. I have given both doors the same layer name because they are both exits.
Basically, it works that I can only press e when I hit this particular collider. However, I don't know how to do it instead of performing two different actions. Maybe there is a way to give the objects a script that I can trigger via the PlayerMovement script. Without taking it into the player.
this is my script that works so far:
void OnInteract(InputValue value)
{
if (myBoxCollider.IsTouchingLayers(LayerMask.GetMask("Entrance")))
{
Debug.Log("interact with the door");
}
}
or is there perhaps a way to listen to the "tag" instead of the layer?
I have also come across interfaces, but have not really understood how these help me. Or how I have to use them here to make them work.
In the end you're going to have to check some kind of tag, layer, or reference a component. it's just your preference. To make it a little simpler you can shoot a raycast in the direction you are looking to check for objects instead of having colliders. But in the end it's doing the same thing.
I don't really use interfaces as I'm pretty new myself but from what I can tell they are generally used for organization and global accessibility in similar objects, like doors lol.

Game Architecture

I have a question about a XNA game I'm making, but it is also a generic question for future games. I'm making a Pong game and I don't know exactly what to update where, so I'll explain better what I mean. I have a class Game, Paddle and Ball and, for example, I want to verify the collisions between the ball with the screen limits or the paddles, but I come across 2 approaches to do this:
Higher Level Approach - Make paddle and ball properties public and on the Game.Update check for collisions?
Lower Level Approach- I supply every info I need (the screen limits and paddles info) to the ball class (by parameter, or in a Common public static class) and on the Ball.Update I check for collisions?
I guess my question in a more generic way is:
Does an object need to know how to update and draw itself, even having dependencies from higher levels that somehow are supplied to them?
or
Is better to process it at higher levels in Game.Update or Game.Draw or using Managers to simplify code?
I think this is a game logic model question that applies to every game. I don't know if I made my question clear, if not, feel free to ask.
The difficult part of answering your question is that you're asking both: "what should I do now, for Pong" and "what should I do later, on some generic game".
To make Pong you don't even need Ball and Paddle classes, because they're basically just positions. Just stick something like this in your Game class:
Vector2 ballPosition, ballVelocity;
float leftPaddlePosition, rightPaddlePosition;
Then just update and draw them in whatever order suits you in your Game's Update and Draw functions. Easy!
But, say you want to create multiple balls, and balls have many properties (position, velocity, rotation, colour, etc): You might want to make a Ball class or struct that you can instance (same goes for the paddles). You could even move some functions into that class where they are self-contained (a Draw function is a good example).
But keep the design concept the same - all of the object-to-object interaction handling (ie: the gameplay) happens in your Game class.
This is all just fine if you have two or three different gameplay elements (or classes).
However let's postulate a more complicated game. Let's take the basic pong game, add some pinball elements like mutli-ball and player-controlled flippers. Let's add some elements from Snake, say we have an AI-controlled "snake" as well as some pickup objects that either the balls or the snake can hit. And for good measure let's say the paddles can also shoot lasers like in Space Invaders and the laser bolts do different things depending on what they hit.
Golly that is a huge mess of interaction! How are we going to cope with it? We can't put it all in Game!
Simple! We make an interface (or an abstract class or a virtual class) that each "thing" (or "actor") in our game world will derive from. Here is an example:
interface IActor
{
void LoadContent(ContentManager content);
void UnloadContent();
void Think(float seconds);
void UpdatePhysics(float seconds);
void Draw(SpriteBatch spriteBatch);
void Touched(IActor by);
Vector2 Position { get; }
Rectangle BoundingBox { get; }
}
(This is only an example. There is not "one true actor interface" that will work for every game, you will need to design your own. This is why I don't like DrawableGameComponent.)
Having a common interface allows Game to just talk about Actors - instead of needing to know about every single type in your game. It is just left to do the things common to every type - collision detection, drawing, updating, loading, unloading, etc.
Once you're in the actor, you can start worrying about specific types of actor. For example, this might be a method in Paddle:
void Touched(IActor by)
{
if(by is Ball)
((Ball)by).BounceOff(this.BoundingBox);
if(by is Snake)
((Snake)by).Kill();
}
Now, I like to make the Ball bounced by the Paddle, but it is really a matter of taste. You could do it the other way around.
In the end you should be able to stick all your actors in a big list that you can simply iterate through in Game.
In practice you might end up having multiple lists of actors of different types for performance or code simplicity reasons. This is ok - but in general try to stick to the principle of Game only knowing about generic actors.
Actors also may want to query what other actors exist for various reasons. So give each actor a reference to Game, and make the list of actors public on Game (there's no need to be super-strict about public/private when you're writing gameplay code and it's your own internal code.)
Now, you could even go a step further and have multiple interfaces. For example: one for rendering, one for scripting and AI, one for physics, etc. Then have multiple implementations that can be composed into objects.
This is described in detail in this article. And I've got a simple example in this answer. This is an appropriate next step if you start finding that your single actor interface is starting to turn into more of a "tree" of abstract classes.
You could also opt to start thinking about how different components of the game need to talk to each other.
Ball and Paddle, both are objects in the game and in this case, Renderable, Movable objects.
The Paddle has the following criteria
It can only move up and down
The paddle is fixed to one side of the screen, or to the bottom
The Paddle might be controlled by the user (1 vs Computer or 1 vs 1)
The paddle can be rendered
The paddle can only be moved to the bottom or the top of the screen, it cannot pass it's boundaries
The ball has the following criteria
It cannot leave the boundaries of the screen
It can be rendered
Depending on where it gets hit on the paddle, you can control it indirectly (Some simple physics)
If it goes behind the paddle the round is finished
When the game is started, the ball is generally attached to the Paddle of the person who lost.
Identifying the common criteria you can extract an interface
public interface IRenderableGameObject
{
Vector3 Position { get; set; }
Color Color { get; set; }
float Speed { get; set; }
float Angle { get; set; }
}
You also have some GamePhysics
public interface IPhysics
{
bool HasHitBoundaries(Window window, Ball ball);
bool HasHit(Paddle paddle, Ball ball);
float CalculateNewAngle(Paddle paddleThatWasHit, Ball ball);
}
Then there is some game logic
public interface IGameLogic
{
bool HasLostRound(...);
bool HasLostGame(...);
}
This is not all the logic, but it should give you an idea of what to look for, because you are building a set of Libraries and functions that you can use to determine what is going to happen and what can happen and how you need to act when those things happen.
Also, looking at this you can refine and refactor this so that it's a better design.
Know your domain and write your ideas down.
Failing to plan is planning to fail
You could see your ball and paddle as a component of your game, and XNA gives you the base class GameComponent that has an Update(GameTime gameTime) method you may override to do the logic. Additionally, there is also the DrawableGameComponent class, which comes with its own Draw method to override. Every GameComponent class has also a Game property which holds the game object that created them. There you may add some Services that your component can use to obtain information by itself.
Which approach you want to make, either have a "master" object that handles every interaction, or provide the information to the components and have them react themselves, is entirely up to you. The latter method is preferred in larger project. Also, that would be the object-oriented way to handle things, to give every entity its own Update and Draw methods.
I agree with what Andrew said. I am just learning XNA as well and in my classes, for example your ball class. I'd have an Update(gametime) method and a Draw() method in it at the least. Usually an Initialize(), Load() as well. Then from the main game class I will call those methods from their respective cousins. This was before I learned about GameComponent. Here is a good article about if you should use that. http://www.nuclex.org/blog/gamedev/100-to-gamecomponent-or-not-to-gamecomponent

XNA AI: Managing Enemies on Screen

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

Problems designing Bejeweled game

I am trying to do the design of a Bejeweled game. I have basically 3 classes. The Game class, which is what is going to be used by the player, a Board class, that represents the board, and a SwitchController class that is responsible for checking if the wanted switch on the board is valid, making the switch, counting the number of possible switches available (so I can know when the game is over, etc).
My current design is something like the following:
Game:
isGameOver()
isSwitchValid(coord1, coord2)
makeSwitch(coord1, coord2)
getPieceAt(coord)
getBoardLength()
IBoard:
getPieceAt(coord)
setPieceAt(coord, piece)
getLength()
My idea would then to have a ISwitchController:
ISwitchController:
isSwitchValid(coord1, coord2)
makeSwitch(coord1, coord2)
getAllValidSwitches()
Here is a little diagram of how the classes are to be organized:
I would have 2 different concrete classes of IBoard available for use (and for each one of them, I'd have to have an ISwitchController implementation).
The problem:
My program is to have 2 IBoard implementations:
The first, ArrayBoard, will have all the pieces of the board stored in a 2D Array. There is nothing special about it. I will define an ArrayBoardSwitchController for managing this class.
The second, ListBoard, will have for each color of pieces, a List/Set with all the coordinates of the pieces of that color. I will define a ListBoardSwitchController for managing this class.
The main issue here is that the implementation of SwitchController will be totally different on ArrayBoard and on ListBoard. For example, while for implementing getAllValidSwitches() ArrayBoardSwitchController only needs the getPieceAt() method, that would not be a good idea to do with ListBoardSwitchController(in that class I use internally lists because it's easier to check if the move is valid that way).
From what I can see, there are 2 different possible solutions:
I could either merge together the
ISwitchController and IBoard
interfaces. That way I'd only have
two classes, Game and Board (while
basically Game would just be a
controller for the Board, as it
would be the Board that had all the
game logic). It wouldn't be that nice
because the classes wouldn't be
as cohese as they could be if I had
3 distinct classes.
Let the interfaces as they are and put
all the methods I need to work with public
in the concrete classes. For example, if I need
a getYellowPiecesList() method, I'd put it public
on ListBoard so ListBoardSwitchController could
use it. ListBoardSwitchController would only
know about it because it knows it only works
against ListBoards.
What's your opinion on the matter? The focus here is not so much on how to design the Bejeweled game, but how to solve this problem, that is recurrent when you try to implement algorithms: on one hand you want to have a clear and good OOP design, and in the other sometimes that gets in the way of having a sound and effective algorithm implementation.
The main issue here is that the implementation of SwitchController will be totally different on ArrayBoard and on ListBoard.
If this is the case, then it sounds like you haven't designed the IBoard interface well enough so that classes can use an implementation of IBoard without knowing the implementation details. If the user of an IBoard needs to know what implementation is being used, then it almost defeats the purpose of having an interface!
I would strongly suggest re-visiting the methods you are exposing on IBoard to see if there is a way you can expose something like "get the piece at this coordinate" in a more generic way. Make sure that any methods a controller needs to invoke on a IBoard instance are only the methods in the IBoard interface.
For example, while for implementing getAllValidSwitches() ArrayBoardSwitchController only needs the getPieceAt() method, that would not be a good idea to do with ListBoardSwitchController(in that class I use internally lists because it's easier to check if the move is valid that way).
If an operation such as "get piece at this coordinate" is instrumental to the IBoard interface, then the implementations must be faithful to their contract and implement it correctly. It sounds as if your ListBoard is not faithfully meeting the contract set out in IBoard.
3: Let ArrayBoardSwitchController and ListBoardSwitchController be inner classes of ArrayBoard and ListBoard. The implementation of the controller is tied to the implementation of your board, thus it makes sense to keep them together. Because the controller will be an inner class you can use the implementation details from the board. Then to make it work extend the IBoard interface to return a ISwitchController.
Note that this is only slightly different from option 1. (The ISwitchController can now be used indirectly from a IBoard, merging them gives direct access to ISwitchController)
What is the purpose of ListBoard as an object decoupled from ArrayBoard? If I were going to bother with the list of gems at all, I would keep it in an object which also held an array of what was in each position, so that swapping the position of two gems could be done quickly and efficiently. Not that I'm clear on why you need the position list anyhow?
If a 6507 running at 1.19Mhz with 128 bytes of RAM and 20% CPU availability can handle Columns, finding all 3-in-a-row combinations on a 6x20 in less than 100ms, I would think more modern machines could scan for moves acceptably fast without using a list of what gems are where. I'd suggest padding your board array so you don't have to worry about edge cases, and for each gem check 16 combinations of various cells within 3 squares of it(*) to see if they both match it. Some moves may be double-reported (e.g. this algorithm may detect that moving a gem left will create a 3-in-a-row, and also detect that moving the gem to the left of the first one right will create a 3-in-a-row) but that shouldn't be a problem.
(*) If a gem can move left, then it must match either the two gems to the left of the destination, or the two gems above the destination, or the two gems below, or one above and one below. Likewise for the other directions.

Categories