call this() constructor and different base() constructor - c#

I have some classes that all extend a parent class. like so:
public abstract class EasyUIELementFoundation
{
protected GameObject UIElement;
private RectTransform RectOptions;
private Vector2 _position;
private Vector2 _dimensions;
protected Vector2 Position
{
get
{
return _position;
}
set
{
RectOptions.pivot = value;
_position = value;
}
}
protected Vector2 Dimensions
{
get
{
return _dimensions;
}
set
{
RectOptions.sizeDelta = value;
_dimensions = value;
}
}
protected EasyUIELementFoundation()
{
UIElement = new GameObject();
RectOptions = UIElement.AddComponent(typeof(RectTransform)) as RectTransform;
}
protected EasyUIELementFoundation(Vector2 position) : this()
{
_position = position;
}
protected EasyUIELementFoundation(Vector2 position, Vector2 dimensions) : this()
{
_dimensions = dimensions;
_position = position;
}
}
public class EasyRawImage : EasyUIELementFoundation
{
private RawImage UIImageComponent;
private Texture2D _image;
public Texture2D Image
{
get
{
return _image;
}
set
{
UIImageComponent.texture = value;
_image = value;
}
}
public EasyRawImage() : base()
{
UIImageComponent = UIElement.AddComponent(typeof(RawImage)) as RawImage;
}
public EasyRawImage(UnityEngine.Object image, Vector2 position) : this() : base(position)
// here is the error it is not possible to call the base.
{
//some code...
}
}
So my problem is i have 3 different base class constuctors and from the derived class i want to call different base constructors, but i cant atm. Is this even possible if not how would i go about doing such a thing?
If anything is unclear let me know so i can clarify.
I am a complete newb to OOP so sorry if this is a bit of a weird question.

Invoking this() will invoke a base constructor, implicitly or explicitly. Therefore, the other invocation of base would be the second time you construct the same object, which is not allowed.
You can share the code of the constructor by creating a private helper method, like this:
public class EasyRawImage : EasyUIELementFoundation
{
private RawImage UIImageComponent;
private Texture2D _image;
public Texture2D Image
{
get
{
return _image;
}
set
{
UIImageComponent.texture = value;
_image = value;
}
}
public EasyRawImage() : base()
{
InitUiImageComponent();
}
public EasyRawImage(UnityEngine.Object image, Vector2 position) : base(position)
{
InitUiImageComponent();
//some code...
}
private void InitUiImageComponent() {
UIImageComponent = UIElement.AddComponent(typeof(RawImage)) as RawImage;
}
}
In your specific case initialization code could be placed directly into the initializer, so the helper method becomes unnecessary:
public class EasyRawImage : EasyUIELementFoundation
{
private RawImage UIImageComponent = UIElement.AddComponent(typeof(RawImage));
private Texture2D _image;
public Texture2D Image
{
get
{
return _image;
}
set
{
UIImageComponent.texture = value;
_image = value;
}
}
public EasyRawImage() : base()
{
}
public EasyRawImage(UnityEngine.Object image, Vector2 position) : base(position)
{
//some code...
}
}

You cannot call a this and a base constructor at the same time. Usually the best approach is as already mentioned in the comment to first implement the constructor that is the most complex (has most parameters) and call the base class. Then make the simpler constructor call the complex ones with default values.
With this approach your class will then end up looking like this:
public class EasyRawImage : EasyUIELementFoundation
{
private RawImage UIImageComponent;
private Texture2D _image;
public Texture2D Image
{
get
{
return _image;
}
set
{
UIImageComponent.texture = value;
_image = value;
}
}
public EasyRawImage() : this(default(UnityEngine.Object), default(Vector2))
{
}
public EasyRawImage(UnityEngine.Object image, Vector2 position) : base(position)
{
UIImageComponent = UIElement.AddComponent(typeof(RawImage)) as RawImage;
//some code...
}
}

Related

How to make a static class Derive by MonoBehaviour

recently I am making a game. There is a script named SizePositionForBullet.cs
the code of it was as:-
using UnityEngine;
using UnityEngine.UI;
public class SizePositionForBullet : MonoBehaviour
{
#region variables
//public variables
public Slider widthSetByUser;
public Slider heightSetByUser;
public Slider posXSetByUser;
public Slider posYSetByUser;
//private variables
public float width;
public float height;
public float posX;
public float posY;
#endregion
void Update()
{
#region Getting Player Prefs
posX = PlayerPrefs.GetFloat("posX", 323);
posY = PlayerPrefs.GetFloat("posY", 175);
width = PlayerPrefs.GetFloat("Width", 150);
height = PlayerPrefs.GetFloat("Height", 150);
#endregion
}
public void GetSliderValue(int pos)
{
if (pos == 1)
{
PlayerPrefs.SetFloat("posX", posXSetByUser.value);
}
if (pos == 2)
{
PlayerPrefs.SetFloat("posY", posYSetByUser.value);
}
if (pos == 3)
{
PlayerPrefs.SetFloat("Width", widthSetByUser.value);
}
if (pos == 4)
{
PlayerPrefs.SetFloat("Height", heightSetByUser.value);
}
}
}
So I need to use it's height , width and posX, posY variable in other class. So I added this code in class
public SizePositionForBullet _instance;
public static SizePositionForBullet Instance
{
get{
if(_instance == null)
{
_instance = GameObject.FindObjectOfType<BulletSizePosition>();
}
return _instance;
}
}
But when I use it in other class as it:-
float width = BulletSizePosition.Instance.width;
Unity saying: Null refrence Exception Object refrence not set to an instance of object at Assets/Scripts/BulletScript
How to solve it?
Your private _instance must be static too.
You are using the Singleton pattern. If this class reflect only player save (playerprefs) you don't have to make inheriting from MonoBehaviour.
public class MyPlayerSettings
{
public float Size;
...
private MyPlayerSettings()
{
LoadPreferences();
}
public void LoadPreferences()
{
// Get all your pref here
Size = PlayerPrefs.GetFloat("Size");
...
}
public static MyPlayerSettings Instance
{
get
{
if(instance == null)
{
instance = new MyPlayerSettings();
}
return instance;
}
}
private static MyPlayerSettings instance;
}

Design Pattern - Decorator. Is correct used in my program?

I have a quesition.
Is in this example did i asue correctly design pattern - decorator?
I want to increase speed of plane after decorate.
Does decorator always has to add new methods? Can only overwrite existing methods?
This is IPlane interface:
interface IPlane
{
void MoveLeft();
void MoveRight();
Rectangle GetPlaneBody();
int GetHealthPoints();
int GetSpeed();
Bullet Shot();
void SetSpeed(int speed);
}
This is plane class:
public class Plane : IPlane
{
private Rectangle PlaneBody = new Rectangle();
private int HealthPoint;
private int x=200;
private int speed;
private Bullet Amunition = new Bullet();
private static Plane instance;
private Plane() { }
public static Plane Instance
{
get
{
if (instance == null)
{
instance = new Plane();
instance.PlaneBody.Height = 125;
instance.PlaneBody.Width = 115;
instance.PlaneBody.X = 200;
instance.PlaneBody.Y =600;
instance.HealthPoint = 1000;
instance.speed = 10;
}
return instance;
}
}
public void MoveLeft()
{
if(x>-10)
x -= speed;
PlaneBody.X = x;
}
public void MoveRight()
{
if(x<1165)
x += speed;
PlaneBody.X = x;
}
public Rectangle GetPlaneBody()
{
return PlaneBody;
}
public int GetHealthPoints()
{
return HealthPoint;
}
public int GetSpeed()
{
return speed;
}
public Bullet Shot()
{
Bullet bullet = new Bullet();
bullet.SetDamage(Amunition.GetDamage());
bullet.SetSpeed(Amunition.GetSpeed());
bullet.SetCoordinates(x+10, this.PlaneBody.Y - 30);
return bullet;
}
public void SetSpeed( int speed)
{
this.speed = speed;
}
}
This is abstract decorator:
class AbstractPlaneDecorator : IPlane
{
protected IPlane plane;
public AbstractPlaneDecorator(IPlane plane)
{
this.plane = plane;
}
public int GetHealthPoints()
{
return plane.GetHealthPoints();
}
public Rectangle GetPlaneBody()
{
return plane.GetPlaneBody();
}
public int GetSpeed()
{
return plane.GetSpeed();
}
public virtual void MoveLeft()
{
plane.MoveLeft();
}
public virtual void MoveRight()
{
plane.MoveRight();
}
public void SetSpeed(int speed)
{
plane.SetSpeed(speed);
}
public Bullet Shot()
{
return plane.Shot();
}
}
And concrete decorator:
class IncreaseSpeedDecorator : AbstractPlaneDecorator
{
public IncreaseSpeedDecorator(IPlane plane) : base(plane)
{
}
public override void MoveLeft()
{
plane.MoveLeft(); // move two times faster
plane.MoveLeft();
}
public override void MoveRight()
{
plane.MoveRight(); // move two times faster
plane.MoveRight();
}
}
This decorator makes that plane moves 2 times faster (He performs the same method twice). Does it meet the rules of decorator pattern?
I would say the implementation is fine.
I don't know the exact context of your code, but it might be a bit strange that if you ask your decorator for the plane's speed, it will return the plane's base speed, but the plane is moving twice as fast. I think a better name for the decorator to describe its funcionality would be DoubleMoveDecorator or something like that, since it doesn't actually do anything with the plane's speed.

Get/Set The Members of a Struct or a Class in a Class C#

If I have a Struct or a Class, lets say I'm using a Vector2 (which has two members, float X and float Y), how am I supposed to properly get/set its methods in a class?
This is the code I know of right now:
public class MyClass
{
private Vector2 vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
}
But what if I wanted to edit the members (or certain members) of the Vector2 with the set method? Something like this is what I'm asking for:
set.X
{
vector.X = value.X;
}
set.Y
{
vector.Y = value.Y;
}
And it would be called as simply as Vector.X = 5. I thought up an alternative, using something like public float VectorX { set { vector.X = value; } } but I would prefer a more logical and object-orientated way. Is there?
It makes a BIG difference whether Vector2 is a class or a struct.
Since Vector2 is a class you can simply do
obj.Vector.X = 5;
having
public class MyClass
{
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
}
If, however Vector2 was a struct then you cannot modify the return value from the get. If you try you will get a compile error:
Cannot modify the return value of ... because it is not a variable.
You can work around this using the method you suggested with
public float VectorX
{
get { return _vector.X; }
set { _vector.X = value; }
}
public float VectorY
{
get { return _vector.Y; }
set { _vector.Y = value; }
}
or you could provide a wrapper class around Vector2 like:
class Vector2Wrapper
{
public Vector2 Vector;
}
and then store a Vector2Wrapper in MyClass like
public class MyClass
{
private Vector2Wrapper _vector2Wrapper;
public Vector2Wrapper VectorWrapper
{
get { return _vector2Wrapper; }
set { _vector2Wrapper= value; }
}
}
and you can then modify it like
obj.VectorWrapper.Vector.X = 5;
you can't specify a submethod to handle that partial set, because that set is handled by the Vector class and us thus out of your scope. the moment someone calls Myobject.Vector they are calling your get funcion, but when it moves on to .X they are calling the Vector.get_X function.
This may be easier to see by looking at the compiled code using the ILDasm tool, which reveals the actual method calls your properties make sugar out of.
Now, what you CAN do is to wrap certain properties, as mentioned. The result would like like so.
public class MyClass
{
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
public float VectorX
{
get { return _vector.X; }
set { _vector.X = value; }
}
public float VectorY
{
get { return _vector.Y; }
set { _vector.Y = value; }
}
}
Another option might be to use the pattern of INotifyPropertyChanged in your Vector class, raising an event every change which your MyClass can then listen to and react to, thus applying logic when child elements are updated.
There is also the option of using an indexer property
public class MyClass
{
public enum Axis { X, Y }
private Vector2 _vector; //Has to be private
public Vector2 Vector
{
get { return vector; }
set { vector = value; }
}
public float this[Axis axis]
{
get { return axis == Axis.X ? vector.x : vector.y; }
set
{
if(axis == Axis.Y)
{
// Special logic here
vector.Y = value;
}
if(axis == Axis.X)
{
// Special logic here
vector.X = value;
}
}
}
}
Because Vector2 is a struct, you are getting a COPY. You need to use the setter to set a new Vector2. There are 2 ways:
Vector2 v = myClass.Vector; //get a copy of the vector
v.X = 5f; // change its value
myClass.Vector = v; // put it back
I don't really like the following, but it's one statement:
myClass.Vector = new Vector2(2f, myClass.Vector.Y)
Inside MyClass, you can create a property that sets only the X value:
public float X {
get { return Vector.X; }
set {
Vector2 v = Vector;
v.X = value;
Vector = v;
}
}
(Vector can be an automatic property)

Error CS1585: Member modifier 'public' must precede the member type and name

Guys I was working on Unity3D's MonoDevelop. I was implementing my classes however I got an error I cannot figure out what is. The problem I get is in the title at the line where I override the abstract methods proceed and isFinished. What is the problem?
namespace tool
{
public class TaskManager
{
public TaskManager ()
{
}
}
public abstract class Task {
public bool isEvitable = true;
public abstract void proceed();
public abstract bool isFinished();
}
public class MoveTask : Task {
float speed;
Vector3 targetPosition;
GameObject movingObject;
private MoveTask(GameObject gameObject, float speed, Vector3 target) {
this.movingObject = gameObject;
this.speed = speed;
this.targetPosition = target;
}
#override
public void proceed() {
Vector3 objPos = movingObject.transform.position;
movingObject.transform.position = new Vector3 (Mathf.Lerp(objPos.x, targetPosition.x, speed),
Mathf.Lerp(objPos.y, targetPosition.y, speed),
Mathf.Lerp(objPos.z, targetPosition.z, speed));
}
#override
public bool isFinished() {
}
}
}
try this. yours is java syntax.
public override void proceed(){
}
public override bool isFinished(){
return false;
}
how about this?
public partial class Form1 : Form
{
ExploitAPI api ; new ExploitAPI
public ExploitAPI Api { get => api; set => api = value; }
public Form1()
{
InitializeComponent();
api.LaunchExploit();
}
private void Button1_Click(object sender, EventArgs e)
{
api.ToggleClickTeleport();
}
}
}
please answer the fix as soon as possible
Best regards, guest

C# how to use the Parent class property in child class

I have following class which has Parent class Shapes which has property Radius and i am accessing this property into its child class(HeaxGon) but it gives me error in child class ( get or set accessor expected)
Please advise.
class Shapes
{
int _radius;
public int Radius
{
get { return _radius; }
set { _radius = value; }
}
}
class HeaxGon:Shapes
{
int points;
public void SetRadius
{
**Radius=20;**
}
}
I am guessing you are trying to create a function called SetRadius, in which case, this is what it should look like:
public void SetRadius(int radius)
{
this.Radius = radius;
}
Or if you really want to set it to 20 in all cases:
public void SetRadius()
{
this.Radius = 20;
}
You wrote it badly, it should look like this:
class Shapes
{
int _radius;
public int Radius
{
get { return _radius; }
set { _radius = value; }
}
}
class HeaxGon:Shapes
{
int points;
public void SetRadius()
{
Radius=20;
}
}
There's no need calling "this" like others have suggested.
Or simply work with the property you've already exposed in your base class
HeaxGon hg = new HeaxGon();
hg.Radius = 20;
This will call your setter you've specified in your base class (Shapes).
Make _radius protected, and then simply call this.Radius in the child class. So:
public class Shape
{
protected int _radius;
public int Radius
{
get { return _radius; }
set { _radius = value; }
}
}
public class Hexagon : Shape
{
int _points;
public void SetRadius(int radius)
{
this.Radius = radius;
}
}

Categories