Declare a variable class - c#

i need to declare a variable class in my code so i can access a function (having the same name in all classes) but doing each time a different behavior).
and this is my code:
using UnityEngine;
using System;
using System.Collections;
public class Bubble : ItemBehaviour
{
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
void OnMouseDown ()
{
theclass.Behaviour ();
}
}
knowing that (theclass gonna be variable ).
Thank you guys for your answer but it is a bit special.
My game is about interaction between player and game objects when the player approach any item that is "interactible" lets say, a bubble shows up, this bubble is a GameObject and it is the same for any object that allow interactions,
So since i am doing a 2D game i thought, it would be great if i make a "universal"
EmptyGameObject that contains all common aspects that anyObject would contain, and i grouped main functions and common ones in a general script and i added it to this emptyGameObject, then i added the Bubble prefab to this Game object and i a dded a code to it this code contains what i wrote in my firs post.
i was thinking that now each time i want an object i just drop this emptygameobject prefab and changes sprites and characteristics.
And each object have a different behavior (ex: i can delete an apple as if the character consumed it but i can not consume a door, the door would rather trigger an animation than being destructed ) i am specifying all this in a class for each item.
now whatever the class is (the object is) the trigger is in the bubble class (which i posted first) but the class will be different each time and i can not make a class that contains polymorphism because its not the same context each time.

I think you should create an interface that declares all the functions you would like to use in different classes.
interface IBehaviour
{
void Behaviour();
void AnotherBehaviour();
}
with this you define a behaviour what a class, which implements the interface, is capable of.
And then your classes would be:
class MyClass1 : Ibehaviour
{
}
class MyClass2 : IBehaviour
{
}
Apart from this you can use abstract classes. There are a lot of well-written articles about these topics on the Internet.
Firstly, I recommend to get familiar with OOP principles.
This link is a good way to start.
Good luck.

Thank you all,
The matter was solved by creating a global (abstract) gameOject that contains the class that we want to inherit from, and then each time the gameObject atached to this class calls (Behavior function) it trigger whatever the override is for this function for this object.

Related

Is there a way to find first component of type?

Ok so basically I have a script which highlights gameobjects with a specific tag if your mouse is pointing at.
After it's highlighted you need to press a specific key and you will execute a public function inside the interactable object. Now the problem is when I want to search a specific component instead of using it's name, any help is expected. :)
Script isn't a type, but Component is the base type for anything that can be attached to a game object (hence GetComponent having the name it does). Components include things like Transform, MeshFilter, etc. Most scripts that you'll write inherit MonoBehaviour, so you totally could do something like GetComponent<MonoBehaviour>() but then you'll get the one (or all, if you use GetComponents) of the MonoBehaviour scripts attached to the game object.
Since you're just blindly getting any script without knowing its type in advance, you're going to wind up with some big if/else chain where you keep trying to downcast the object to a concrete type that you can actually do something with.
The solution is to use an interface. If multiple classes can all do the same thing, then make an interface that encapsulates that functionality. In your case you might have an IUseKeystrokes interface for all the kinds of classes you could make that would use your keystroke sequence technique.
public interface IUseKeystrokes
{
void Use(char keystroke);
}
Then you add that to any class you're writing and you'll get a compile error if you don't implement the Use(char) method.
public class MyThing : MonoBehaviour, IUseKeystrokes
{
public void Use(char keystroke);
// and other stuff for the class
}
and now finally you can call
IUseKeystrokes useKeystrokes = targetGameObject.GetComponent<IUseKeystrokes>();
and now it actually doesn't matter what class it is, no need to downcast, you just call
useKeystrokes.Use(keystroke);

how do i go about cleanly implementing varying behaviours extending the same abstract method while simultaneously needing varying parameters?

i've just gotten around to using Scriptable Objects inside unity. and i've been wanting to use it to "drag and drop" different logic into another abstract class that will be extended upon later down the line.
more precisely what i want to do is to have a weapon class that can target other positions in the game world, but i need to do so slightly differently based on what kind of weapon it's going to be. for example, maybe i want the weapon to target enemies randomly on a global scale (think lightning strikes), or maybe i want to target the closest enemy from my players position(simple). or maybe i want to target multiple enemies in a certain area around me (damaging aura, shotguns), etc, etc.
now the problem isn't with the creating the logic on how to get these positions and such. the problem that i have is that i want to put all these differing ways to target enemies in each their own scriptable objects, so i can essentially drag and drop in my weapon what kind of targeting type the weapon will use. so what i need is to be able to call different logic with the same method name, let's say we make it an abstract named "Target()", now i can extend the abstract class with the function Target() everytime i need a different targeting implementation, and be able to call it without hassle, right?
well... thats not all. the thing is, i may need differing parameters for different targeting implementations. so yes i can overload the abstract method, create new overloads for all the different parameters i may use. but i don't think this is very practical, because if i do that, i'll at most end up implementing only one of those overloads in each class. and i don't feel like this is a good way to solve the problem.
another solution i've been thinking about is creating just one abstract method with all the parameters it could possibly need, and use only the parameters i need, for the particular implementation. though that still has me needing to assign all parameters all the time even when i won't use em. so instead those parameters i've been thinking of sending a struct. assign only the data i need within it and then send it off.
p.s after writing this post out, i'd like to add that i could make the parameter generic as well, and have a variety of structs to send, as to avoid unfilled/unused variables, your thoughts?
now ultimately my question is. is all of this okay? or 'good practice'. and if it's not, what should i do instead?
Thank you!
Code Bits:
here is the relevant part of my weapon class as it is now, i'm using Enums (TargetingTypes) to assign the weapon what kind of targeting (method) it will pick.
public void DetermineTargetingMode()
{
switch (targetingType)
{
case TargetingTypes.AutoTargetClosest:
TargetClosest();
break;
case TargetingTypes.RandomTarget:
TargetRandom();
break;
case TargetingTypes.RandomTargetWithinRange:
TargetRandomWithinArea();
break;
case TargetingTypes.AllTargetsWitninRange:
TargetAllWithinArea();
break;
}
}
public void TargetClosest() //returns a single target
{
FireWeapon(TargetingTools.GiveClosestTargetPoisitonFromArray(transformCache.position, WaveManager.instance.enemiesAlive.ToArray()));
}
public void TargetRandom() //returns a single target
{
FireWeapon(TargetingTools.GiveRandomTargetPositionFromArray(WaveManager.instance.enemiesAlive.ToArray()));
}
public void TargetRandomWithinArea() //returns a single target
{
FireWeapon(TargetingTools.GiveRandomTargetPositionFromArrayWithinRange(transformCache.position, WaveManager.instance.enemiesAlive.ToArray(), areaOfEffect));
}
public void TargetAllWithinArea() //returns an array of targets
{
FireWeapon(TargetingTools.GiveAllTargetPositionsWithinRange(transformCache.position, WaveManager.instance.enemiesAlive.ToArray(), areaOfEffect));
}
and although this works functionally fine, i feel it could be a lot more extendable/flexible.
for example i think i could offload the content of each of these functions to seperate scriptableObjects like this
My solution:
(the abstract scriptable object)
public abstract class TargetingType : ScriptableObject
{
public abstract T Target<T>(TargetingData data);
}
the scriptable object where i would implement the 'target the closest single enemy' logic
public class TargetClosestSingleEntity : TargetingType
{
public override T Target<T>(TargetingData data) //maybe make the parameter generic as well so i can send more 'appropriate' and 'tailored' structs, avoiding unfilled/unused variables what do you guys think?
{
var dataToReturn = "xD";
return (T)Convert.ChangeType(dataToReturn, typeof(T));
}
}
and (pseudo)implemented the weapon class would look like so
public abstract class WeaponBases : MonoBehaviour, IWeapon
{
public WeaponConfiguration configuration; //just some data container, cooldown of weapon, damage source, name, etc
public TargetingType targetingType; // assigned what type in unity editor, let's just imagine i slotted the 'close single target' one.
private TargetingData targetingData;
public abstract void FireWeapon(Transform target); // where the class extending this will decide what to do with the target.
public abstract void FireWeapon(Transform[] targets); // ditto, but if an array gets returned.
public void AimAndFire() //placeholder names for now
{
FireWeapon(targetingType.Target(targetingData)); /* let's just imagine i've magically assigned the data to targetingData as needed,
* Target() must either return either a transform or a transform[]. */
}
}

Unity/C# what's wrong with the way I think about this problem

I have an abstract parent class called Item
From this I inherent to Equipment and from here to Weapon and Armor. Since I want my weapons to have varying behavior, I want my logic to operate on the classes. From my Item class I also inherit to a Resource class, which should be static. My Equipment class shouldn't and should be instansiable , since an individual sword eg. Can be sharpened or damaged, to change it from its base class without changing all other swords. So I need to clone these class instances. But since cloning a class is a very non forward thing to do, I was wondering if I am doing something wrong in my architecture, and thinking about the problem in the wrong way? Do anyone have any thoughts? /Mikael
I think you should consider setting the 'stats' for items in a file (xml or such) and then create a Factory class that can give you a file with all the stats already set.
i.e.
public abstract ItemFactory{
public static Sword GetSword(){
var sword = new Sword();
//Set stats for sword from file
return sword;
}
}
Why use cloning when you can just use referencing? If I understand your problem correctly, I would utilize ScriptableObjects for defining your item objects, which makes them Assets in your project. Which then can be assigned via the inspector.
The general class layout could look something like this.
class Equipment : ScriptableObject
{
public int goldCost;
}
class Weapon : Equipment
{
public intDefaultSharpness;
}
These are your definition classes, remember they are to define the general properties of each item category. So you might have a Sword, but not a "Broadsword of fiery Dragonkiller". If you check the link about ScriptableObjects you will find code that allows you to instantiate new Assets from these definition classes. Now you can create your Broadsword and ofc many more. Now your objects just become assets like Textures and 3D models. You can easily edit them in the inspector (and probably want it to make it even nicer with custom editors)
Similar to a texture or 3D Model we don't copy it every time we use it, instead we reference it. So when your player character holds a weapon you have a sub GameObject that just keeps a reference to the original object and any additional "local" data.
class PlayerWeapon : GameObject
{
public Weapon template;
public int durability;
}
The nice thing is, the template Weapon is assignable via inspector in the editor, as it is just a normal asset. And the durability property is local to this playerWeapon and the GameObject could be used multiple times.
Of course, this can be expanded on as much as you want. I would probably add getter/setter to hide additional calculation based on buffs/debuffs. Something like
public int AttackStrength
{
get
{
return owner.strength + template.strength
}
}

What is MonoBehaviour in Unity 3D?

using UnityEngine;
using System.Collections;
public class VariablesAndFunctions : MonoBehaviour
{
int myInt = 5;
}
The full code is here Unity Official Tutorials
What is the purpose of MonoBehaviour
MonoBehaviour is the base class from which every Unity script derives. It offers some life cycle functions that are easier for you to develop your app and game.
A picture is worthy of thousands of words.
Source of the image: https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg
While the following statement is correct,
"MonoBehaviour is the base class from which every Unity script derives" -
I honestly feel it can be misleading to beginners. The phrase - "every Unity script" - being the culprit.
It gives a beginner the notion that all scripts created in unity must extend Monobehaviour. Which is not the case. You can create scripts that house classes that extend the c# base object class. In doing so, your script is then categorised as not a Unity script but nothing stops it from interacting with other Unity scripts and vice versa.
MonoBehaviour is another class that VariablesAndFunctions is inheriting from. This allows the inheritor to use the methods and variables of the other class providing they have the correct access level modifier set.
In the below example Class1 inherits from Base and so can use the protected method Method1
public class Base
{
protected void Method1 { /*...*/ }
}
public class Class1 : Base
{
public void Method2 { Method1(); }
}
Note in this particular example it would be better for Method1 to be marked as abstract or virtual so then Class1 can override it like so:
protected override Method1()
{
//...
base.Method1(); //Call the implementation of Method1 in Base here
//...
}
In particular though MonoBehaviour is described as being:
MonoBehaviour is the base class from which every Unity script derives.
Therefore when doing scripting in unity, you use this base class to better control how things are accessed so you do not need to do it yourself.
Monobehavior is what most of your scripts inherit from,
if you go to the documentation Click here!
you will see a bunch of variables and methods you get from this Inheritance.
such as:
Public Methods
Messages
Properties
Public Methods
Static methods
The most commonly used method (its under message in the documentation but honestly its better to see it as a function) is Update , its the main game loop, the speed at which the update function is called is based on your fps. But the important thing to take away is that if you didn't inherit from monobehavior, you wouldn't have access to this game loop.
Another important function that you get from Monobehavior is Start, which is called once on a script, and it's called after awake, so if you want to set some variables up you can do it here.
The important thing to take is that if you made a simple C# class that inherits from nothing, you wouldn't have access to these methods discussed. Monobehavior gives you access to many functions that help you build your game.
There are other behaviors your scripts can inherit from like ScriptableObject and StateMachineBehaviour, which give you access to other methods, but Monobehavior is the most common behavior your scripts will inherit from.
It's also good to note that whenever you use Monobehavior, it comes with a transform, some other scripts (Scriptable objects) don't come with a transform. The transform is simply a position in your game/scene where the gameobject lies its an x,y,z coordinate with rotation and scale.

Query Regarding Design of Class-based Text Adventure Game.

I've been learning C# over the summer and now feel like making a small project out of what I've done so far. I've decided on a sort of text based adventure game.
The basic structure of the game will involve having a number of sectors(or rooms). Upon entry into a room, a description will be outputted and a number of actions and such you may take; the ability to examine, pick up, use stuff in that room; possibly a battle system, etc etc. A sector may be connected up to 4 other sectors.
Anyway, scribbling ideas on paper on how to design the code for this, I'm scratching my head over the structure of part of my code.
I've decided on a player class, and a 'level' class that represents a level/dungeon/area. This level class would consist of a number of interconnected 'sectors'. At any given time, the player would be present in one certain sector in the level.
So here's the confusion:
Logically, one would expect a method such as player.Move(Dir d)
Such a method should change the 'current sector' field in the level object. This means class Player would need to know about class Level. Hmmm.
And Level may have to manipulate the Player object (eg. player enters room, ambushed by something, loses something from inventory.) So now Level also needs to hold a reference to the Player object?
This doesn't feel nice; everything having to hold a reference to everything else.
At this point I remembered reading about delegates from the book I'm using. Though I know about function pointers from C++, the chapter on delegates was presented with examples with a sort of 'event based' programming viewpoint, with which I did not have much enlightenment about.
That gave me the idea to design the classes as follows:
Player:
class Player
{
//...
public delegate void Movement(Dir d); //enum Dir{NORTH, SOUTH, ...}
public event Movement PlayerMoved;
public void Move(Dir d)
{
PlayerMoved(d);
//Other code...
}
}
Level:
class Level
{
private Sector currSector;
private Player p;
//etc etc...
private void OnMove(Dir d)
{
switch (d)
{
case Dir.NORTH:
//change currSector
//other code
break;
//other cases
}
}
public Level(Player p)
{
p.PlayerMoved += OnMove;
currSector = START_SECTOR;
//other code
}
//etc...
}
Is this an alright way to do this?
If the delegate chapter was not presented the way it was, I would not have thought of using such 'events'. So what would be a good way to implement this without using callbacks?
I have a habit of making highly detailed posts... sorry v__v
What about a 'Game' class which would hold the majority of the information like a Player and a current room. For an operation such as moving the player, the Game class could move the player to a different room based on the room's level map.
The game class would manage all the interactions between the various components of the games.
Using events for something like this brings the danger that your events will get tangled. If you're not careful you'll end up with events firing each other off and overflowing your stack, which will lead to flags to turn events off under special circumstances, and a less understandable program.
UDPATE:
To make the code more manageable, you could model some of the interactions between the main classes as classes themselves, such as a Fight class. Use interfaces to enable your main classes to perform certain interactions. (Note that I have taken the liberty of inventing a few things you may not want in your game).
For example:
// Supports existance in a room.
interface IExistInRoom { Room GetCurrentRoom(); }
// Supports moving from one room to another.
interface IMoveable : IExistInRoom { void SetCurrentRoom(Room room); }
// Supports being involved in a fight.
interface IFightable
{
Int32 HitPoints { get; set; }
Int32 Skill { get; }
Int32 Luck { get; }
}
// Example class declarations.
class RoomFeature : IExistInRoom
class Player : IMoveable, IFightable
class Monster : IMoveable, IFightable
// I'd proably choose to have this method in Game, as it alters the
// games state over one turn only.
void Move(IMoveable m, Direction d)
{
// TODO: Check whether move is valid, if so perform move by
// setting the player's location.
}
// I'd choose to put a fight in its own class because it might
// last more than one turn, and may contain some complex logic
// and involve player input.
class Fight
{
public Fight(IFightable[] participants)
public void Fight()
{
// TODO: Logic to perform the fight between the participants.
}
}
In your question, you identified the fact that you'd have many classes which have to know about each other if you stuck something like a Move method on your Player class. This is because something like a move neither belongs to a player or to a room - the move affects both objects mutually. By modelling the 'interactions' between the main objects you can avoid many of those dependencies.
Sounds like a scenario I often use a Command class or Service class for. For example, I might create a MoveCommand class that performs the operations and coordinations on and between Levels and Persons.
This pattern has the advantage of further enforcing the Single Responsibility Principal (SRP). SRP says that a class should only have one reason to change. If the Person class is responsible for moving it will undoubtedly have more than one reason to change. By breaking the logic of a Move off into its own class, it is better encapsulated.
There are several ways to implement a Command class, each fitting different scenarios better. Command classes could have an Execute method that takes all necessary parameters:
public class MoveCommand {
public void Execute(Player currentPlayer, Level currentLevel) { ... }
}
public static void Main() {
var cmd = new MoveCommand();
cmd.Execute(player, currentLevel);
}
Or, sometimes I find it more straightforward, and flexible, to use properties on the command object, but it makes it easier for client code to misuse the class by forgetting to set properties - but the advantage is that you have the same function signature for Execute on all command classes, so you can make an interface for that method and work with abstract Commands:
public class MoveCommand {
public Player CurrentPlayer { get; set; }
public Level CurrentLevel { get; set; }
public void Execute() { ... }
}
public static void Main() {
var cmd = new MoveCommand();
cmd.CurrentPlayer = currentPlayer;
cmd.CurrentLevel = currentLevel;
cmd.Execute();
}
Lastly, you could provide the parameters as constructor arguments to the Command class, but I'll forgo that code.
In any event, I find using Commands or Services a very powerful way to handle operations, like Move.
For a text-based game, you're almost certainly going to have a CommandInterpretor (or similar) object, which evaluates the user's typed commands. With that level of abstraction, you don't have to implement every possible action on your Player object. Your interpreter might push some typed commands to your Player object ("show inventory"), some commands to the currently-occupied Sector object ("list exits"), some commands to the Level object ("move player North"), and some commands to specialty objects ("attack" might be pushed to a CombatManager object).
In that way, the Player object becomes more like the Character, and the CommandInterpretor is more respresentational of the actual human player sitting at the keyboard.
Avoid getting emotionally or intellectually mired in what the "right" way to do something is. Focus instead on doing. Don't put too much value on the code you've already written, because any or all of it may need to change to support things that you want to do.
IMO there's way too much energy being spent on patterns and cool techniques and all of that jazz. Just write simple code to do the thing you want to do.
The level "contains" everything within it. You can start there. The level shouldn't necessarily drive everything, but everything is in the level.
The player can move, but only within the confines of the level. Therefore, the player needs to query the level to see if a move direction is valid.
The level isn't taking items from the player, nor is the level dealing damage. Other objects in the level are doing these things. Those other objects should be searching for the player, or maybe told of the player's proximity, and then they can do what they want directly to the player.
It's ok for the level to "own" the player and for the player to have a reference to its level. This "makes sense" from an OO perspective; you stand on Planet Earth and can affect it, but it is dragging you around the universe while you're digging holes.
Do Simple Things. Any time something gets complicated, figure out how to make it simple. Simple code is easier to work with and is more resistant to bugs.
So firstly, is this an alright way to
do this?
Absolutely!
Secondly, if the delegate chapter was
not presented the way it was, I would
not have thought of using such
'events'. So what would be a good way
to implement this without using
callbacks?
I know a lot of other ways to implement this, but no any other good way without some kind of callback mechanism. IMHO it is the most natural way to create a decoupled implementation.

Categories