简体   繁体   中英

How can i re-use a code in monobehaviour class?

First i'd like to give a short version of my question: How can i access another code pieces attached to another game object, or how can i initiazlie a class without have an game object attched.

When i making a small game in Unity, i made an unit designer where you give some value such as how many weapon does it carry, and the status of that unit (attack, range, speed, etc.) will be calculated by ComputeValues() and saved when you click confirm. But all those values were adjusted by clicking a button instead of direct input. (Ie Click a button and add/reduce 1 weapon)

However, when i try to add some template unit at start up it won't work. So i made a CreateDesignWithValue() function. Which takes input for all the related data, and use the ComputeValues() above to compute the value for that object.

The problem is i'm trying to do it in player class. But i can't create new ShipDesigner, and neither can i set it to static. How can i get access to it?

Without knowing you exact usecase and what the methods do you are talking about we can only give a very general answer:

Not all classes have to be of type MonoBehaviour it really depends on your needs.

Extension Methods

If you have a certain calculation for a certain type you can use Extension Methods like

public static class Vector3Extensions
{
    public static Vector3 DevideBy(this Vector3 a, Vector3 b)
    {
        return new Vector(a.x / b.x, a.y / b.y, a.z / b.z);
    }
}

which you can use like eg

var newVector = transform.position.DevideBy(new Vector(1, 2, 3));

in all other classes.

public static class

In general you can use a public static class to implement methods and store values that shall be executable from everywhere eg

public static class Settings
{
    private static int _currentInt = 7;

    public static void SaySomething(string something)
    {
        Debug.Log(something);
    }

    public static void DoubleCurrentInt()
    {
        _currentInt *= 2;
    }

    public static int GetSquareOfCurrentInt()
    {
        return _currentInt * _currentInt;
    }
}

which you can call now from everywhere like

Settings.DoubleCurrentInt();
Settings.SaySomething(Settings.GetSquareOfCurrentInt.Tostring);

Instances

Ofcourse sometimes you do not want that something is accessible from everywhere so you can also simply have a normal instanced class for your calculation like

public class Settings
{
    private int _currentInt = 7;

    public Settings(int initialInt = 0)
    {
        _currentInt = initialInt;
    }

    public void SaySomething(string something)
    {
        Debug.Log(something);
    }

    public void DoubleCurrentInt()
    {
        CurrentInt *= 2;
    }

    public int GetSquareOfCurrentInt()
    {
        return CurrentInt * CurrentInt;
    }
}

So you can use

private Settings settings;

private void Start()
{
    new Settings(3);
}

in one MonoBehaviour and

private Settings settings;

private void Start()
{
    new Settings(26);
}

in another MonoBehaviour , both have different instances but can use all the implemention in it for calculating and doing stuff individually.

public static void

you can also only "share" one method among all instances of a certain type ( static ) and also allow other types to access it ( public )

public class A : MonoBehaviour
{
    // A prefab only this specific component has access to
    [SerializeField] private GameObject prefab;

    // example for a kind of singleton pattern
    private static GameObject prefabSingleton;

    private void Start()
    {
        prefabSingleton = prefab;
    }

    public static void Spawn(int someIntToAssign, string someTextToAssign)
    {
        var obj = Instantiate(prefabSingleton)

; componentReference = obj.GetComponent();

        componentReference.someIntField = someIntToAssign;

        componentReference.Getcomponent<Text>().text = someTextToAssign;
    }
}

this you can call from other types as well like

A.Setup(someExampleReference, "Yeay!");

(in this example you could consider to rather implement it in SomeExampleType , though ^^)

ScriptableObjects

What you described also sounded like ScriptableObjects ( Tutorial ) might be interesting for you.

ScriptableObjects are kind of assets similar to prefabs but can store values and also methods. You than can reference them in fields of MonoBehaviour components to change their behaviour according to the values or in order to share it as kind of container between multiple instances and different types.

Instance with public method

Last but not least the most "usual" of doing it would be to have a

public class A : MonoBehaviour
{
    [SerializeField] private Transform someObject;

    public Vector3 GetObjectPosition()
    {
        return someObject.position;
    }
}

and access it via one of the many GetComponent or/and FindObjectOfType variants or simply by referencing the according component like

public class B : MonoBehaviour
{
    // drag in via the Inspector
    public A AReference;

    private void Start()
    {
        // or get it on runtime e.g.
        AReference = GameObject.Find("ObjectWithA").GetComponent<A>();

        // or if there is only one e.g.
        AReference = FindObjectOfType<A>();


        Debug.Log(AReference.GetObjectPosition());
    }
}

Answer of short versions:


How can i access another code pieces attached to another game object : Declare a public field for the script you want to reach eg public ExampleScript exampleScript; and assign the gameobject which has ExampleScript to your field in the inspector.


how can i initiazlie a class without have an game object attched : You can't create an instance of a script derived from MonoBehaviour just like new ExampleScript(); . But instead you can add that script to your existing gameobject with gameObject.AddComponent<ExampleScript>(); and you can reach this script from another script which is attached the very same gameObject like: gameObject.GetComponent<ExampleScript>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM