Setting parent in instantiated class

I am trying to get bullets to fire from a parented position. In the Weapon.cs Awake() function I create 2 gunports, pass the parent transform and a Vector3 to offset the position from the parent. When I run the code I get the following error from GunPort.cs:

NullReferenceException
GunPort…ctor (UnityEngine.Transform _owner, Vector3 _offsetPosition) (at Assets/GunPort.cs:37)
Starfighter.Awake () (at Assets/Starfighter.cs:63)

This error points to where I set the transform.parent to the passed _owner.transform. I have done something similar with parenting a camera to physical object with success and I dont know why there is a problem with the way I have done it here. The _owner is not null as it suggests which I verified from using the statement Debug.Log(_owner.ToString());. Please excuse the Itallic text it is not intentional. The only difference is that my GunPort does not have a physical object, its invisible, as intended.

Weapon.cs:

void Awake () {
	gunPort = GetComponent<GunPort>();
	gunPorts = new GunPort[2];
	gunPorts[0] = new GunPort(transform, new Vector3(-10, 0, 0));
	gunPorts[1] = new GunPort(transform, new Vector3(10, 0, 0));
}

void CheckFiringPrimaryWeapon()
{	
	if(shipControls.IsFiringPrimary)
	{
		Bullet clone;
		clone = Instantiate(bullet, gunPorts[0].Position, transform.rotation) as Bullet;
		clone = Instantiate(bullet, gunPorts[1].Position, transform.rotation) as Bullet;
	}
}

GunPort.cs:

public class GunPort : MonoBehaviour {
private Transform owner;

public Vector3 Position
{
	get { return transform.position; }
}

public GunPort(Transform _owner, Vector3 _offsetPosition)
{
	transform.parent = _owner.transform;
	transform.localPosition = 
		(Vector3.right * _offsetPosition.x) +
		(Vector3.up * _offsetPosition.y) +
		(Vector3.forward * _offsetPosition.z);
}
}

You shouldn’t be using the Constructor on objects which derive from MonoBehaviour! The problem is that the object gets ‘created’ in a different way from how you would expect it to. Use Instantiate, and then pass in variables with an Init(Transform owner, Vector3 offset) method. Also, you don’t need to use _owner.transform in your parenting line. _owner.transform will always return _owner, since it is already a transform! You may as well use

transform.parent = _owner;

It is more efficient, since it does not use component lookups like Component.transform does.

I think I get what you are saying though I am having some trouble trying to implement it. I’m quite new at unity so I hope you will bear with me. I created an empty GameObject, renamed it to GunPort, and attached my GunPort script to it.

In my Main.cs file I added:

public GameObject port;

Then attached the GunPort GameObject to it within the Unity Editor Inspector.

In the Awake() function I Instantiated the GunPorts as follows (where Init replaces the constructor from the OP in GunPort.cs):

	gunPorts = new GunPort[2];
	gunPorts[0] = Instantiate(port) as GunPort;
	gunPorts[0].Init(transform, 1, new Vector3(10, 0, 0));
	gunPorts[1] = Instantiate(port) as GunPort;
	gunPorts[1].Init(transform, 1, new Vector3(-10, 0, 0));

The problem I have is that the Instantiate() does not return anything, as I get the error:

NullReferenceException: Object reference not set to an instance of an object
Starfighter.Awake () (at Assets/Starfighter.cs:66)

The error happens on the Init() call, debugging shows that gunPorts[0] is null. I’m not sure what I have done wrong.

OK, I figured out where I went wrong. I should have created port as GunPort and not a GameObject. Thanks for your help in this.