I'm fairly new to C# so I'm still getting used to it.
I've had this code going where I want to control a character with a virtual joystick. I was testing whether the joystick would be responsive or now, but every time I try to play the scene, I get 3 CS0535 errors saying:
'VirtualJoystick' does not implement interface member UnityEngine.EventSystems.IPointerUpHandler.OnPointerUp(UnityEngine.EventSystems.PointerEventData)'
'VirtualJoystick' does not implement interface member UnityEngine.EventSystems.IDragHandler.OnDrag(UnityEngine.EventSystems.PointerEventData)'
'VirtualJoystick' does not implement interface member `UnityEngine.EventSystems.IPointerDownHandler.OnPointerDown(UnityEngine.EventSystems.PointerEventData)'
Here's the code. It's fairly short.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
private Image bgImg;
private Image joystickImg;
private Vector3 inputVector;
private void start()
{
bgImg = GetComponent<Image>();
joystickImg = transform.GetChild(0).GetComponent<Image>();
}
public virtual void onDrag(PointerEventData ped)
{
Vector2 pos;
if(RectTransformUtility.ScreenPointToLocalPointInRectangle(bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos))
{
Debug.Log("Test");
}
}
public virtual void onPointerDown(PointerEventData ped)
{
onDrag(ped);
}
public virtual void onPointerUp(PointerEventData ped)
{
}
}
I hope you guys could help me through this.
EDIT:
I have corrected the syntax, which was cause of why the scene was not playing. But the Debug.Log on OnDrag code is not working. I'm getting this NullReferenceException: Object reference not set to an instance of an object error. Again, I'm just following what the video says, and his seems to work just fine.
You have declared the methods virtual, since the base class declares them virtual already, you have to declare them with override.
So:
public override void OnPointerUp(PointerEventData ped) { }
Also note that with C# your naming should match exact, so OnPointerUp instead of onPointerUp.
Correct your spelling, i.e. onPointerDown -> OnPointerDown. C# is case sensitive.
When your class inherit from interface(s), it should implement all methods and properties declared on such interface(s).
In your case you must declare in your class the methods mentioned in the compiling error messages, respecting their parameters type and returning values, all case sensitive.
Interfaces are meant to make sure all classes that inherit from them implement such methods and properties. Therefore you could access those members without more knowledge about the class itself.
Interfaces do not declare method/property modifiers (private, public, etc). You can specify them as you see fit.
idraghandler,ipointeruphandler,ipointerdownhandler implement in this order
Related
I'm working on a hobby project in Unity. I have MonoBehaviour scripts for my characters that use component objects for each behavior the character has. When I create new characters, I inherit a new class from the base class for whichever component behaves differently.
When certain triggers occur, I send characters back to their initial state by calling a Reset() method exposed by the base class that sets fields back to their initial values. I'm wondering how to send that call down through the inheritance chain. Right now, the base class has a protected virtual ChildReset() that gets called in Reset() and does nothing by default. If child classes have fields to reset, they override this method. It feels like a really awkward way of doing it.
I like the idea of implementing something similar to the messaging system Unity uses. If a monobehavior doesn't use the Update() message, then the class just doesn't define an update. It eliminates unnecessary calls. I have no idea how I would do something like that.
Any thought invested in this is much appreciated! I've written out the way my project is structured below just in case these details are useful for answers.
public class Character : MonoBehaviour
{
private Motion motionController;
private Interaction characterInteractionController;
//etc
private void Update()
{
motionController.DoStuff();
characterInteractionController.DoStuff();
}
private void Reset()
{
motionController.Reset();
characterInteractionController.Reset();
}
private void OnEnable() => ResetTrigger.OnReset += Reset;
private void OnDisable() => ResetTrigger.OnReset -= Reset;
}
public class Motion : Component {}
public class Interaction : Component {}
public abstract class Component
{
public void Reset()
{
/* set fields to default values */
ChildReset();
}
protected virtual void ChildReset() { }
public abstract void DoStuff();
}
There is no need to send a call down through the inheritance chain. You do not have two different objects. An object of the child class contains everything declared in the base class. Why not directly make Reset() virtual?
public abstract class Character : MonoBehaviour
{
public virtual void Reset()
{
...
}
}
public class ChildCharacter : Character
{
// If ChildCharacter has stuff to reset, override this method, otherwise don't!
public override void Reset()
{
base.Reset(); // Call this to reset stuff from the base class.
//TODO: reset child stuff.
}
}
If Reset is overridden in the child class, then calling Reset will call ChildCharacter.Reset() even if called on a variable statically typed as Character.
Character c = new ChildCharacter();
c.Reset(); // calls ChildCharacter.Reset() when overridden
If Reset is not overridden in the child class, then calling Reset will call Character.Reset() even if called on a ChildCharacter.
ChildCharacter child = new ChildCharacter();
child.Reset(); // calls Character.Reset() when not overridden.
I'm making my rpg game in unity. As I need a lot of different weapons, I tried to make a script for each weapons. Then instead of enacting the Attack function in each weapon's object, I wanted to controll them in other class such as WeaponManager for some reason.
However, I got no idea how to manage variety of classes. It doesn't seem efficient to write all the codes for each classes, such as
if((gameObject).name=="Wand")
gameObject.Getcomponent<Wand>().Attack();
else if((gameObject).name=="Sword")
gameObject.Getcomponent<Sword>().Attack();
... and so on.
In other way, I also thought of SendMessage function, but it doesn't seem like efficient as well.
I'm wodering how can I solve this problem. Which method can I use?
Classical example use case for object oriented programming:
Inheritance!
Use a shared parent class both inherit from and either implement the method virtual with a shared default behavior the inheriting classes can overwrite/extend or make it abstract so inheriting classes have to implement it.
public abstract class Weapon : MonoBehaviour
{
public abstract void Attack();
// alternatively implement some default behavior
// in this case the child classes can but don't have to override this
//public virtual void Attack()
//{
// Debug.Log("Harr Harr .. but I'll do nothing else!", this);
//}
}
and then
public class Wand : Weapon
{
public override void Attack()
{
...
}
}
and
public class Sword : Weapon
{
public override void Attack()
{
...
}
}
then simply go
gameObject.GetComponent<Weapon>().Attack();
I have camera script class that do culling task and it contains these variables and an event :
protected float CullDetailSmall = 25.0f;
protected float CullDetailMedium = 80.0f;
protected float CullDetailLarge = 130.0f;
protected float CullDetailExtraLarge = 250.0f;
protected float CullDetailXExtraLarge = 450.0f;
protected float CullDetailXXExtaLarge = 650.0f;
public virtual void Awake(){
//culling apply logic using above variable values
}
The camera script class is the base class for CamFly and CamWalk. Now i want to change the base class camera script variable values, so I make this function in each class (CamFly and CamWalk)
public void SetCullingValues(int cullDetailSmall
, int cullDetailMedium
, int cullDetailLarge
, int cullDetailExtraLarge
, int cullDetailXExtraLarge
, int cullDetailXXExtaLarge
, int CullFloor
)
{
base.CullDetailSmall = cullDetailSmall;
base.CullDetailMedium = cullDetailMedium;
base.CullDetailLarge = cullDetailLarge;
base.CullDetailExtraLarge = cullDetailExtraLarge;
base.CullDetailXExtraLarge = cullDetailXExtraLarge;
base.CullDetailXXExtaLarge = cullDetailXXExtaLarge;
base.CullFloor = CullFloor;
base.Awake();
}
It is working fine and doing what i want but its certainly not a good piece of code. I am amzed that how can i do it correctly?? Remember
i am calling above function under some conditions, like if some
condition are matched then execute above function and change base
class variable.
second i want to this for both inherited members.
Please check the next link from Microsoft with relevant abstract class documentation and best practices.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract
An abstract class is used as a base template for derived classes. It is used to enforce a design rule.
abstract class YourClass
{
public int a;
public abstract void A();
}
class Example : YourClass
{
public override void A()
{
Console.WriteLine("Example.A");
base.a++;
}
}
have Camera script class that do culling task and it contains these variables and an event
I see no event, I see a void returning virtual method named Awake.
It is working fine and doing what i want but its certainly not a good piece of code
What makes you think that? Yes, its improvable but I've seen far worse.
I am amzed that how can i do it correctly
Yeah, that happens to all of use sometimes...
My two cents of advice:
In general, do not expose fields directly. If the fields are subject to modification, use read/write properties. This way you can always ensure that the state of your base class remains consistent.
Name methods appropiately so the name conveys what the method does. SetCullingValues does not make it clear that the method will also call Awake. Either call it SetCullingValuesAndAwake or do not call Awake.
Why is SetCullingValues even declared in the derived types? Declare it in the base type.
1 and 3 assumes you have access to Camera. If you don't then there is not much you can do to improve what you already have.
The need :
To have the possibility to interact with Component instances of different type attached on GameObject instances through an interface.
For exemple, if I have a game with soldiers, and assuming that medics and snipers both are soldiers, I want to be able to get the Soldier component attached to a soldier GameObject, regardless of whether that soldier is actually a Sniper or a Medic. Then, I could do something as follows : soldier.GetComponent<Soldier>().Respawn(); which would end up calling either Medic.Respawn() or Sniper.Respawn(), depending on the actual type of the soldier.
Possible but dirty solution 1 :
A first naive approach would be to have the Sniper and Medic components implement a Soldier interface. However, this causes several problems.
For example, if you want to check whether a GameObject has a component implementing Soldier, you can't, because Soldier is only an interface, not an actual Unity Component. Thus, calling GetComponent<Soldier>() on a GameObject having, for exemple, a Medic component would not return that Medic component, even if Medic does implement Soldier.
(Actually you could check this by iterating over all the components and using the is operator, but that would be dirty and slow).
Possible but dirty solution 2 :
A second approach is to create a base Component class Soldier from which the Medic and Sniper classes would inherit.
But this also poses several problems.
First, the Unity events (Awake(), Start(), etc) are only going to be called on the leaf classes of the hierachy, forcing you to manually call the same functions on the parent class. Anyone who has tried that knows that it's easy to forget calling something, which results in improperly initialized objects, for example.
And second, the usual problems of inheritance are here too. For exemple, if I want my Medic and Sniper componenents to not only be Soldier, but also be Explodable or VehicleDriver or whatever, I can't, because C# does not support multiple inheritance.
The approach I'm thinking about :
I've thought about a way to design my code so that the issues listed above are solved.
The idea is to have a Component class that acts as the interface and have that interface component coexist with the acutal component on the same GameObject. In other words, let two game objects. One of them would have both a Soldier and a Medic component and the other one would have both a Soldier and a Sniper component. All three component classes, i.e Soldier, Medic and Sniper would be completely separate and all inherit from MonoBehaviour.
The other parts of the code would only interact with the Soldier component. In this case you would be able to do : soldier.GetComponent<Soldier>().Respawn();.
Then, it would be the resposibility of the "interface" component (i.e Soldier) to use the actual component (i.e Medic or Sniper) in order to perform the specific action.
However, since Soldier does not known anything about Medic, Sniper or whatever implementation might be added in the future, the Soldier component exposes an actual interface that the Medic and Soldier have to implement.
Since it is possible to implement multiple interfaces, using this solution, it would be possible to use more than one "interface" component. For exemple, a soldier game object could have the following "interface" components : Soldier and Explodable, and the following "actual" componenent : Medic which would implement both interfaces Soldier.ISolder and Explodable.IExplodable.
What do you think about this solution ? Thx !
EDIT :
I coded what I had in mind and it seems to work nicely. I've also created an editor script allowing to have the "interface" component reference the "actual" component without having public fields, but properties instead. I'll post the code, just in case someone wants it :
WaterComponent.cs - The "interface" component for water objects :
using System;
using UnityEngine;
public class WaterComponent : MonoBehaviour
{
#region Interface
public interface IWater
{
bool IsPointSubmerged(Vector3 worldPoint);
Vector3 GetNormalAtPoint(Vector3 worldPoint);
}
#endregion Interface
#region Properties
public IWater Water
{
get
{
return waterImplementation;
}
set
{
Component asComponent = value as Component;
if (null != value && null == waterComponent)
{
throw new ArgumentException($"The given {typeof(IWater).Name} is not a {typeof(Component).Name}.");
}
waterComponent = asComponent;
waterImplementation = value;
}
}
#endregion Properties
#region Fields
[SerializeField]
private Component waterComponent;
private IWater waterImplementation;
#endregion Fields
#region Public methods
public bool IsPointSubmerged(Vector3 worldPoint)
{
return waterImplementation.IsPointSubmerged(worldPoint);
}
public Vector3 GetNormalAtPoint(Vector3 worldPoint)
{
return waterImplementation.GetNormalAtPoint(worldPoint);
}
#endregion Public methods
#region Unity events
private void Awake()
{
waterImplementation = waterComponent as IWater;
}
#endregion Unity events
}
RealWater.cs - The "actual" component implementing the "interface" component :
using UnityEngine;
public class RealWater : MonoBehaviour, WaterComponent.IWater
{
#region WaterComponent.IWater implementation
public bool IsPointSubmerged(Vector3 worldPoint)
{
return SpecificIsPointSubmerged(worldPoint);
}
public Vector3 GetNormalAtPoint(Vector3 worldPoint)
{
return SpecificGetWaterAtPoint(worldPoint);
}
#endregion WaterComponent.IWater implementation
#region Non-public methods
private bool SpecificIsPointSubmerged(Vector3 worldPoint)
{
return true;
}
private Vector3 SpecificGetWaterAtPoint(Vector3 worldPoint)
{
return transform.up;
}
#endregion Non-public methods
}
WaterComponentEditor.cs - The custom editor allowing not to have naked fields exposed :
using UnityEditor;
[CustomEditor(typeof(WaterComponent))]
[CanEditMultipleObjects]
public class WaterComponentEditor : Editor
{
#region Serialized properties
private SerializedProperty waterProperty;
#endregion Serialized properties
#region Overridden methods
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(waterProperty);
if (EditorGUI.EndChangeCheck())
{
((WaterComponent) target).Water = waterProperty.exposedReferenceValue as WaterComponent.IWater;
}
serializedObject.ApplyModifiedProperties();
}
#endregion Overridden methods
#region Unity events
private void OnEnable()
{
waterProperty = serializedObject.FindProperty("waterComponent");
}
#endregion Unity events
}
Feel free to reuse, unless you see a flaw with this, in which case I'd would really like to know about it !!
EDIT : Well the problem with that custom editor is that you can have the "interface" component reference any Component even if the latter does not implement the real interface exposed by the "interface" component. It is still possible to do some run time checks in the custom editor script, but that's not so clean. However I think the advantages remain good enough in comparison to that issue.
Well...
GetComponent family of functions now supports interfaces as generic argument.
Unity 5.0 release notes : https://unity3d.com/fr/unity/whats-new/unity-5.0
Whatever...
Ok so I am making a game using XNA, I would like all of the enemies to extend from one base class called "baseEnemy.cs". For example, I would like a zombie to have a class called "zombie.cs" but make it entend the "baseEnemy.cs".
I think I remember being told its would be laid out like:
class zombie : baseEnemy
{
}
But I am assuming the use of get{} and set{} would help me to change values of current variables in zombies.cs that exist as part of baseEnemy.cs... If that makes sense? I don't understand the usage of get{} and set{} but I have seen it in other languages (such as the code for minecraft) which I would assume are similar in their working.
So, say I have a float for the speed of the enemy... I don't want all the enemies to move at the same speed (zombie's should have a low speed, etc). How could I get the speed from the baseEnemy.cs and set it as the speed in zombie.cs.
Or would I be better just making the variables public in baseEnemy.cs?
Sorry if the above doesn't make much sense, I am not too experienced with XNA or terminology used and therefore I probably sound like I am going round in circles :S
You are looking for so called abstract methods or abstract properties.
abstract class Enemy
{
public abstract float GetSpeed();
}
class Zombie : Enemy
{
public override float GetSpeed()
{
return 10;
}
}
Note the abstract keyword preceding the class name and the method name. The child class has to implement all abstract members, if it is not abstract itself. When an abstract member is implemented the override keyword must be used.
The get set syntax you are describing is called a property. It is a special C# construct that organizes the getter and/or setter of a field and puts them in a single block. The same example as above using properties:
abstract class Enemy
{
public abstract float Speed { get; }
}
class Zombie : Enemy
{
public override float Speed
{
get { return 10; }
}
}