- Home /
Reference to a general type of script independent of its class name
I want to have a class to reference a script, but that script is not the same every time. For example:
public class PlayerController : MonoBehaviour {
public InputActions inputActions;
public MonoBehaviour jumpController;
private void Awake()
{
inputActions.PlayerActions.Jump.performed += context => jumpController.Jump();
}
}
I have 3 classes for JumpController (with differents class names) that implement the same methods (same names) but in differents ways. I want to switch in the inspector between these classes without change the code in the PlayerController class. The problem is that I can't access to a script methods without specificing his exact name. Is there a way to accomplish this?
Hello.
You can just declare it as a Object.
Object FinalScript;
ScriptA TheScriptA;
ScriptB TheScriptB;
FinalScript = TheScriptA;
Answer by Hellium · Feb 25, 2020 at 09:42 PM
You are looking for Interfaces.
public interface IJumpController
{
void Jump();
}
public class PlayerController : MonoBehaviour {
public InputActions inputActions;
public GameObject jumpController; // Unity can't serialize interfaces
private void Awake()
{
inputActions.PlayerActions.Jump.performed += context => jumpController.GetComponent<IJumpController>().Jump();
}
}
Then, make your classes with the Jump
method implement the IJumpController
interface
public class ExampleJumpController : MonoBehaviour, IJumpController
Another option is inheritance. You can have a base class implement a method that can be overridden by child classes. Then you can refer to that base class, and its methods (and pretty much any other member, unlike with interfaces) with more flexibility.
For instance:
public class SportsballPlayer : $$anonymous$$onoBehaviour
{
public float jumpheight = 0.5;
public virtual void Jump()
{
transform.position = transform.position += Vector3.up * jumpheight;
}
}
public class $$anonymous$$ichaelJordan : SportsballPlayer
{
public override void Jump()
{
base.Jump();
Debug.Log("Come on and SLA$$anonymous$$");
{
}
public class StephenCurry : SportsballPlayer
{
public override void Jump()
{
transform.position = new Vector3(0, 10000, 0);
}
}
Then you could assign $$anonymous$$ichaelJordan or StephenCurry to a SportsballPlayer field, and call the jump function on either.
There's pros and cons between interfaces vs. inheritance. Interfaces restrict you to enforcing methods only (no values, etc, though technically you can have methods with return types that force you to provide a desired value) but you can also have multiple interfaces on the same object. With inheritance, you couldn't have $$anonymous$$ichaelJordan inherit from any other class but SportsballPlayer, which can be a pretty big design constraint if you rely on them too much, but also let you reuse code a lot from its base classes - imagine if the base version of Jump had a lot of intricate logic. There's other pros and cons but that's the gist.
Your solution is also interesting, but no more than your explanation about the advantages and disadvantages of using interfaces or inheritance Thanks to you too.
Your approach is just what I was looking for. I am ashamed that I didn't realize that I could use the interfaces to implement it after having spent several hours thinking about it . I guess yesterday I had spent too much time working. Thanks a lot.
Your answer
Follow this Question
Related Questions
Cleaning project? After uninstalling an asset 1 Answer
Noob q: how to access functions in script that is in asset folder/view? 1 Answer
Create Unity App that read c# files ? 0 Answers
What is the best way to create this Scoresystem ? 1 Answer
,Getting a Spawner Manager Script to reference a Spawner 1 Answer