It is not necessary to mark the variable as public in order to make it appear in the Editor. Just just put the SerializeField attribute on top of the private variable and it should show up in the Editor.
[SerializeField]
private GameObject cam1;
You can also do the opposite which is make public variable not show in the Editor. This can be done with the HideInInspector attribute.
[HideInInspector]
public GameObject cam1;
But there is another method in Unity to get a GameObject, by avoiding
drag/drop ?
Yes. Many ways.
If the GameObject already exist in the scene then You can with one of the GameObject.FindXXX functions such as GameObject.Find, GameObject.FindGameObjectWithTag
For example,
[HideInInspector]
public GameObject cam1;
// Use this for initialization
void Start()
{
cam1 = GameObject.Find("Name of GameObject");
}
If the GameObject is just a prefab then put the prefab in a folder named Resources then use Resources.Load to load it. See this for more thorough examples.
Finally if you just want to get the component of that GameObject, just like your cam1 variable which is not a GameObject but a component, First, find the GameObject like I did above then use the GetComponent function to get the component from it.
private Camera cam1;
// Use this for initialization
void Start()
{
GameObject obj = GameObject.Find("Main Camera");
cam1 = obj.GetComponent<Camera>();
}