Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by urvashi412 · May 02, 2017 at 02:19 PM · c#classinheritancedelegates

How to set different classes at runtime

I am making a game where the character will have different characteristics and movement functions in each scene. So I am trying to have different script for player in different scenes, while all of them inheriting from same base class. The definition will be something like below

    public class PlayerScript1 : PlayerBase{ /* for scene 1*/
     public void Move(){
      /* my movement code*/
     }
     }

Similarly, I have a separate class for Scene2 as

  public class PlayerScript2 : PlayerBase{ /* for scene 2*/
         public void Move(){
          /* my movement code*/
         }
         }

Now the problem is, my other scripts, like HealthScript,ScoreScript etc they do not change with scene. But they do access PlayerScene1 script. And thats why, I have the PlayerScene1 declaration in them. Like below:

 public class HealthScript :MonoBehaviour{
 PlayerScript1 playerScript;
 void Start(){
 /*accessing the script attached to game object*/
 }
 }
 

So how do I manage different scenes to have different PlayerScripts?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by FM-Productions · May 02, 2017 at 06:52 PM

Hi, In my opinion, there are 2 easy solutions to this.

  1. Define an interface and make PlayerScript2 and PlayerScript1 implement it. The interface has to have all functions of the PlayerScript defined that you want to use in your general scripts like HealthScript, ScoreScript etc. Then, in your general scripts instead of using a specific instance of PlayerScript1 or PlayerScript2 you work with the interface.

  2. This will be easier to implement in your case: Instead of defining PlayerScript1 playerScript; in scripts like HealthScript, you write PlayerBase playerScript; - in short you use your base class in scripts that do not change in different scenes. Then in the PlayerBase class you define the functions where you want to use the specific implementations of PlayerScript1 and PlayerScript2 as virtual, like that:

public class PlayerBase{ public virtual void Move(){ /* my movement code*/ } }

In the derived classes, you override functions like Move() like so:

public class PlayerScript1: PlayerBase{ public override void Move(){ /* my movement code*/ } }

So when you are using the type PlayerBase in one of your scripts like HealthScript and assign an instance of PlayerScript1 to it, you can call the function Move() - because it is also defined in the base class - and it will execute the function like implemented in PlayerScript1, since you have overridden the method.

Then you could simply place a gameObject in you scene that has either the script PlayerScript1 or PlayerScript2 and access it in your general scripts like this:

public class HealthScript :MonoBehaviour{ PlayerBase playerScript; void Start(){ /*finding the player object in your scene*/ PlayerBase player = (PlayerBase)FindObjectOfType(typeof(PlayerBase)); } void Update(){ /*moving the character*/ player.Move(); } }

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image urvashi412 · May 05, 2017 at 11:52 AM 0
Share

Thank you so much. Exactly what i needed. God bless you :D

avatar image
0

Answer by Bunny83 · May 02, 2017 at 07:04 PM

You haven't mentioned the most important thing: Why are those other scripts referencing your "PlayerScript". The name "PlayerScript" does tell us anything about what that script actually does. PlayerScript1 and PlayerScript2 are fundamentally two completely different scripts. One can't be treated as the other. However both can be treated like a "PlayerBase" instance, just like every class can be treated as a System.Object.

Your other scripts might want to declare a variable of PlayerBase instead. However that of course limits the access to things defined inside PlayerBase. You can't access anything that is defined inside PlayerScript1 or 2.

Keep in mind when using inheritance and you want to override a method in a derived class, you have to declare that method in the base class either as virtual or abstract. If you declare it as abstract, the whole class has to be abstract as well.

 public class PlayerBase : MonoBehaviour
 {
     public int someCommonVariable;
     protected virtual void Move()
     {
         Debug.Log("PlayerBase-->Move");
     }
     protected virtual void Update()
     {
         Move();
     }
     public virtual int GetValue()
     {
         return 0;
     }
 }
 
 
 public class PlayerScript1 : PlayerBase
 {
     public int anotherVariable = 5;
     protected override void Move()
     {
         Debug.Log("PlayerScript1-->Move");
         // Specific implementation here
     }
     public override int GetValue()
     {
         return anotherVariable;
     }
 }
 
 public class PlayerScript2 : PlayerBase
 {
     public int anotherVariable = 345;
     protected override void Move()
     {
         Debug.Log("PlayerScript2-->Move");
         // Specific implementation here
     }
     public override int GetValue()
     {
         return anotherVariable;
     }
 }

Have a look at my example. The base class devines an Update method and calls the virtual Move method. Move inside the base class does nothing. However each derived class implement their own behaviour. Move will automatically be called from Update.

Note that each class PlayerScript1 and 2 define a variable names "anotherVariable". However even both a named the same, they have nothing in common and can't be accessed in an abstract way. They are two completely different variables. However each class also overrides the virtual GetValue method that returns an int value. Each script returns the value of it's "anotherVariable". Since GetValue is defined inside the base class you can call it on a base class reference.

So other scripts might have a variable like this;

 public PlayerBase player;

And can simply do:

 Debug.Log("Value is: " + player.GetValue());

If the actual player script is PlayerScript1 GetValue will return "5" (unless the value has changed of course). If the script is a PlayerScript2 instance GetValue will return "345".

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

An OS design issue: File types associated with their appropriate programs 1 Answer

Inherited member variables not set to base value c# 1 Answer

Loading component by superclass. 1 Answer

How to make a custom class inherited from Unity's GUI? 0 Answers

Can I/Should I call Awake() in parent class manually? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges