- Home /
inheriting a class, but wanting it to instantiate on each gameobject it's applied to?
Basically I have a parent class script, called Card which has all the variables and logic in the methods, that will apply to a set of ten cards.
public class Card : MonoBehaviour {
public Texture MainTexture;
public Texture HoverTexture;
public int health;
public string cardName;
public bool selected;
public bool hover;
public virtual void Start ()
{
selected = false;
hover = false;
health = 50;
}
public virtual void Update ()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if (selected != true)
hover = true;
if (Input.GetMouseButtonDown(0))
{
if (selected)
{
selected = false;
hover = true;
}
}
}
}
}
note: the code is pared down to save room, I for example have extra logic to make sure hover is put to false when not over, etc. so there's not problem there.
Then I have a child class that will represent each of the individual cards, such as fire and aquatic, so I can change things like their names from within this child class.
public class CardAquatic : Card {
public override void Start ()
{
base.Start();
cardName = "aquatic";
}
public override void Update ()
{
base.Update();
}
I then add this child script to the game object card (one for fire and one for aquatic) this allows me access to all of the variables in the Card parent class on the inspector so I can assign the specific textures and track the values.
However when I start the game, both cards act as one. (they always share the same hovered or select status :( )
I imagine its because both their parents is simply one class and is seen as one single instance, even though I have created two separate children of that class, and was hoping for them to have individual individual inherited variables.
So is there a way I can make this work? Without sacrificing the useful aspect of having the parent have all the common logic and methods that all cards will use, but have each instance of the child be individual and not share the same parent variables.
As this method allows me to change the overall common logic of all cards, without having to copy and paste to each individual card (there will be 10+)
Hope you can help!!!
Inheritance shouldn't be a problem.I don't get what should make the difference in your children cards?
What is selected for and where is set to true? Again, inheritance is not the problem, there should be something wrong in the logic.
selected and hovered are public booleans defined in the Card parent class.
hover is set to true when the mouse is hovered over (and false when hovered away) selected is when the user clicks while hovered is true. and disabled when clicked again.
here is the full method, just in case there is something wrong that I really didn't see before. (shortened it in the OP cause i didn't think it was the problem)
Truly apologise if the error is in here, and i didn;t think to include it all :(,
public class Card : $$anonymous$$onoBehaviour {
Ray ray;
RaycastHit hit;
public Texture $$anonymous$$ainTexture;
public Texture HoverTexture;
public Texture SelectTexture;
public int health;
public int attack;
public string cardName;
public string weakTo;
public string strongTo;
public bool selected;
public bool hover;
// Use this for initialization
public virtual void Start ()
{
selected = false;
hover = false;
health = 50;
}
// Update is called once per frame
public virtual void Update ()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if (selected != true)
hover = true;
if (Input.Get$$anonymous$$ouseButtonDown(0))
{
if (selected)
{
selected = false;
hover = true;
}
else
{
selected = true;
hover = false;
}
}
}
else
{
hover = false;
}
Draw();
}
void Draw()
{
if (hover)
{
renderer.material.mainTexture = HoverTexture;
}
else if (selected)
{
renderer.material.mainTexture = SelectTexture;
}
else
{
renderer.material.mainTexture = $$anonymous$$ainTexture;
}
}
}
as always thanks so much for giving your time to trying to help me, and i apologise if im being dumb.
You should move that raycast to another script that runs once - right now you are doing as much raycastings as cards you've got - and next, you should check that raycast to see what collider is hitting - right now whenever it hits something it turns true, that's the reason why all cards show hover.
Thanks so much for the advice, that sounds like it will solve the problem. :)
ill work out the solution and post back here.
Answer by wildex999 · Mar 16, 2014 at 06:14 PM
Inheriting from a base class should not make two instances share the same values on variables, unless the field is static.
Can you share the code where you instantiate the cards? Sounds like you keep two references to the same instance.
The only other script in the project is CardParent Which simply compiles all the child transofrms under an empty object called "All Cards". so the script on this empty object which holds as its children the cards is the following.
public class CardParent : $$anonymous$$onoBehaviour {
public List<Transform> CardList = new List<Transform>();
void Start ()
{
foreach(Transform card in this.transform)
{
CardList.Add(card);
}
}
void Update ()
{
}
}
Here is an image of one of the cards in the interface to understand how I added the CardAquatic script which is the second part of the code on my original post, that inherits from the Card Class overall.
And here's an image in game showing that with Aquatic selected in the inspector, the mouse is actually over Fire, yet aquatic stlil shows as hover being true. showing that the two cards are being treated as one card overall, ins$$anonymous$$d of two seperate instances.
Again any more suggestion would be massively appreciated.
Thanks.
Answer by jbecana · Mar 17, 2014 at 06:57 AM
I would create a Player() script and put the card selection code in its Update():
// Select card
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 1 << CardLayer))
{
// Only cards in CardsLayer
// Take advantage of inheritance in next lines
Card myCard = hit.transform.GetComponent<Card>();
if (myCard is CardAquatic)
{
//doCardAquaticTask
}
else if ((myCard is CardXXXX)
{
//doCardXXXTask
}
Using a layer would assure that you are only selecting card types, but it's not strictly required because you're checking for a card component next.
Ins$$anonymous$$d of rayvasting, the On$$anonymous$$ouseDown function should be placed in the Card script. I find it to be more readable.
Sure, On$$anonymous$$ouseDown should be in the Card script. Readability may depend on your design, some people prefer keep player inputs centralized in one script. Anyway, I think your approach may integrate easier in this case.