I am trying to make a main script for a game that I am making in Unity 3D.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
class Main
{
public GameObject ship;
[RuntimeInitializeOnLoadMethod]
static void OnRuntimeMethodLoad()
{
GameObject player = Object.Instantiate (ship, transform.position, Quaternion.identity) as GameObject;
}
}
However, this gives me an error: An Object Reference is Required for non-static field, method, or property 'Main.Ship'
Is it possible to instantiate an object without inheriting MonoBehaviour?
As explained by the previous answers, you are mixing instance scope and class (static) scope.
While several methods have been mentioned that can lead to this script working in the way you started it (you can use the static Resources class to search the assets for a filename), I would like to suggest doing it the other way around, and making your class a MonoBehaviour. While this may sound counter-intuitive to people who have coded in c and prefer to have a clear entry point to their code, its very useful in many cases to get used to the fact that you need to add a GameObject that will contain your main script somewhere.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
class ShipInstanceCreator: MonoBehaviour
{
public GameObject ship;
void Start()
{
GameObject player = Object.Instantiate (ship, transform.position, transform.rotation) as GameObject;
}
What are the benefits? First and main benefit is the fact that whatever inherits from MonoBehaviour gets full support from UnityEditor - so you get free 'Inspector' windows, where you can drag and drop stuff, have sliders etc for free, you get the 'enable/disable' checkbox, you get callbacks when enable/disable state is changed, you get your local transform component (which is often surprisingly useful), you get collisions etc.
Unity will also be able to serialize its state without doing it manually, which means you get a fully defined life-cycle of an object (which can act really funky in the editor when parts of the assembly get reloaded and some don't).
Such script can also instantiate enemy ships and asteroids (at its own transform position and orienation), and because functionality differences between them can (and should) be implemented as behaviours specific to a given prefab, there is no need for your instancer class to know anything else about what it instanes, other than it should be a GameObject
Finally, in a well written Unity project there rarely is a 'main' class. It works best if you split up responsibilites into seperate components, with as little as possible dependencies between them (dependency on UnityEngine is ok). Rather than 'writing a main script' you should be writing a 'InstantiatePlayerScript' and quite possibly it's almost done and you can move on to writing another script that will define another behaviour. That's why they are called Behaviours. Instantiating a player is a behaviour that modifies scene and it should live on the scene like other objects, rather than try to 'sit on the cloud' as a god object, supervising everything from high above. While its absolutely possible to write a game like that, that way becomes much harder as complexity grows.
There are some parts of a game that are ok to make global (ie MusicManager - there's only a single music that you shuold be playing at a single time) but for things like player - what if one day you want to make your game multiplayer? While Singleton Pattern (aka writing a main class somewhere) works ok for many things in Unity, its very easy to overdo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With