Spawn a required component?

Some of the objects in my game are getting some lengthy lists of required components and objects in order to work properly.

I’m thinking I’d like to be able to have my code spawn required elements for these objects to use. In some cases I just want to make sure there is something in case I forget it, in other cases I just don’t want to bother creating the element to add because its just using default properties.

The basic syntax I am thinking of would be like:

public Transform somePointINeedToCheck;

	void Start () {
		if(somePointINeedToCheck == null){
			NewObject = Spawn(GameObject);
			somePointINeedToCheck = NewObject.transform;
		}
	}

Although I’m thinking I want to also create individual components for a class, like this extra script:

private SomeClass MyClass;

	void Start () {
		if(MyClass == null){
			MyClass = Spawn(SomeClass);
		}
	}

But of course, “Spawn” doesn’t work.
Is there another command that will? Something that will create another component or a game object?
And what is the proper syntax for making this assignment?

I’m at work so this is gonna be quick but I hope it’s enough to get you started!

// Create a fresh GameObject.
GameObject newObject = new GameObject("NameOfNewObject");
// Attach whatever MonoBehaviour you want.
SomeClass newClassInstance = newObject.AddComponent<SomeClass>();

Thanks!

I got the second script by using:

		if(myClass == null) {
			myClass = gameObject.AddComponent<ThatClass>();
		}

And now I’ll work on the extra game objects.
Hmm, is there any way to create them as being children to the current game object, so that their transform is relative to said object?

Yes there is!

// From your last comment
if(myClass == null) { 
  myClass = gameObject.AddComponent<ThatClass>();
}

// Make myClass a child of the current MonoBehaviour's transform
myClass.transform.parent = transform;

// A lot of times I want to reposition the child based on
// the current script's transform
myClass.transform.localPosition = Vector3.zero;
myClass.transform.localScale = Vector3.one;
myClass.transform.rotation = transform.rotation;

Okay, I ran into a problem when I tried to do this for some transforms I needed on some pawns. (They are used to check some extra collisions according to set points relative to the pawn.)

Setting things up in the editor, I had a public variable for a transform, and I simply created an empty game object, made it a child of the pawn, and then dragged that game object into the empty slot for it on the pawn’s properties in the inspector.

But to make the pawn create this using scripts I can’t use “gameObject.AddComponent()” because you can’t add a second transform to a game object. I need to create a whole new game object.

I see that there is the “instantiate” command, but the tutorial only shows this for spawning prefabs. I want to spawn an empty game object so I can use its transform. What is the syntax for that?

Pawn pawn = ... // However you get a handle to your pawn...

// To create a blank GameObject, use the new keyword instead of Instantiate().
GameObject freshGameObject = new GameObject("NewGameObject");

// Note: freshGameObject is an empty gameObject that already has a transform on it.
freshGameObject.transform.parent = pawn.transform;
pawn.publicTransformVariable = freshGameObject.transform;

Hi,
Try this to create an empty game object:

myobject = new GameObject("Empty");

Thanks!

BTW, “pawn” was the class I was building this in; it’s just a generic term to refer to any “human” or “character” object in my game. (I use a lot of terminology from Unreal, because that’s my background. That might also be why I feel I should set this stuff in the code instead of the editor.)

The code I have now is:

	public Transform rearGroundCheck;

...

		if (rearGroundCheck == null) {
			GameObject NewRCheck = new GameObject("RearGroundCheck");
			rearGroundCheck = NewRCheck.transform;
			rearGroundCheck.transform.parent = transform;
			rearGroundCheck.transform.localPosition = new Vector3(-1f, centerGroundCheck.transform.localPosition.y, 0);
			Debug.LogWarning("This pawn did not have any rear ground check set.");
		}

Looks good! I only have one more comment. rearGroundCheck is already a Transform, so rearGroundCheck == rearGroundCheck.transform.

That is, getting the .transform property of a Transform just returns itself.

public Transform rearGroundCheck;
// ...
  // rearGroundCheck.transform.parent = transform;
  rearGroundCheck.parent = transform;
  // rearGroundCheck.transform.localPosition = new Vector3(-1f, centerGroundCheck.transform.localPosition.y, 0);
  // if centerGroundCheck is also a Transform:
  rearGroundCheck.localPosition = new Vector3(-1f, centerGroundCheck.localPosition.y, 0);