Creating new GameObject, not Instantiate.

I have a prefab of a mob I want to put in the scene, the problem is I need to target individuals that are created from that prefab and manipulate the scripts on them. I know you cant access scripts from instantiated objects. how would I go about this? or where is the documentation?

PS, C# please.

Yes you can, same as any other GameObject. The only difference is you may need to retrieve a reference to the GameObject, whether through the Instantiate call or using another method such as GameObject.Find, transform.Find, etc.

Just one example of how to get the component script instead of dealing with the GameObject directly.

// Assign in inspector
public SomeMonoBehaviour m_prefab;

void Start() {
  SomeMonoBehaviour someInstance = Instantiate(m_prefab) as SomeMonoBehaviour;
  someInstance.SomeMethod();
}

I stand corrected.
Can i give names to these instantiated objects? for example, say i spawn 4 mobs, my targeting system lets me tab through them. I want to buff the selected target mobs attack speed.
so i would use something like

Rigidbody gspawn = Instantiate(goulPrefab,new Vector3(xSpawn, ySpawn, zSpawn), Quaternion.identity)as Rigidbody;

right?

And lets say i have a script on my player that has the “buff” call on it. how would i pass the buff call to that gameobject if all 6 mobs are exactly the same in every way? o.O

Do you want to change the game object name, the name in the hierarchy?

gspawn.name = "Goul";

I’m not sure how your Player’s Buff() method is written. Here’s probably how I would handle something like that. EDIT: I assumed each of your units have a Goul script attached to them.

public Goul goulPrefab;

void Start() {
  Goul[] gouls = new Goul[4];
  for (int n = 0; n < gouls.Length; n++) {
    gouls[n] = Instantiate(goulPrefab) as Goul;
  }
  selectedGoul = gouls[0];
}

public void Buff() {
  // There are a ton of ways to do a "buff"
  // One way is to tell the unit to buff itself.
  selectedGoul.GoFaster();
}

Goul selectedGoul { get; set; }

never thought of putting the buffs on the goul itself, thank you for the idea!

i have a problem with the script referencing though.

goulBuffs = GameObject.Find (“Goul”).GetComponent ();

in the GameObject.Find what do i find? the prefab? or… im stuck.

GameObject.Find() only finds active game object that are in the scene. It will not find prefabs. In your example, GameObject.Find(“Goul”) will find a game object named “Goul”. If you have more than one such game object, you should assume it’ll pick one at random. It’s considered bad to use any of the Find functions every frame.

// Find one goul in the scene.
// EDIT: We are actually finding a GameObject
GameObject goul = GameObject.Find("Goul");

if (goul != null) {
  // We found an active goul in the scene. Find the buffs script.
  GoulBuffs buffs = goul.GetComponent<GoulBuffs>();
  if (buffs != null) {
    // We found the GoulBuffs script attached to "Goul"
    buffs.DoTheBuff();
  }
}

// To do it all at once:
GameObject.Find("Goul").GetComponent<GoulBuffs>().DoTheBuff();
// This will crash the game if there is no game object named Goul,
// or it has no GoulBuffs on it.

Generally, if you have a lot of gouls, I’d make a GoulManager that tracks all the active gouls, so you aren’t always trying to find one.

Instead of trying to wrap my head around what was laid out already, here are my scripts.

the first one is the spawn script where i pass the newly made goul to a list in Targeting, the 3rd script is attached to the goul itself.

using UnityEngine;
using System.Collections;

public class NecroSpawn : MonoBehaviour {
	public Targeting targeting;
	public Rigidbody goulPrefab;
	//goul attack vars
	public float attackRate = 1f;
	float coolDown;
	public int goulHealth = 5;
	public int maxGoulCount = 1;

	void Update(){
		targeting = GameObject.Find ("Player").GetComponent<Targeting> ();
		//controlls player attack
		if (Time.time >= coolDown) {
			if(maxGoulCount <=5){
				if (Input.GetKeyDown (KeyCode.F)) {
				goulSpawn ();
				maxGoulCount++;

				}
			}
		}
	}
	//goul spawn at feet of player
	void goulSpawn(){
		//position
		float xSpawn = transform.localPosition.x + (Random.Range (-4,4));
		float ySpawn = transform.localPosition.y;
		float zSpawn = transform.localPosition.z;
		//spawn
		Rigidbody gspawn = Instantiate(goulPrefab,new Vector3(xSpawn, ySpawn, zSpawn), Quaternion.identity)as Rigidbody;
			coolDown = Time.time + attackRate;
		targeting.targetsList.Add (gspawn.gameObject);
	}
		//goul taking damage
	void goulDamaged(int damage){
		
		if (goulHealth > 0){
			goulHealth -= damage;
		}
		if (goulHealth <= 0) {
			goulHealth = 0;
			Destroy(gameObject);
		}
	}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Targeting : MonoBehaviour {
	public Transform goulTarget;
	public NecroSpawn necroSpawn;
	public Gouloriginal Goul;
	public List<GameObject> targetsList;
	public GameObject selectedTarget;
	private Transform myTransform;
	// Use this for initialization
	void Start () {
		targetsList = new List<GameObject> ();
		selectedTarget = null;
		myTransform = transform;
	}
	private void SortTargetsByDistance(){
				if (selectedTarget != null) {
						targetsList.Sort (delegate(GameObject t1, GameObject t2) {
								return Vector3.Distance (t1.transform.position, myTransform.position).CompareTo (Vector3.Distance (t2.transform.position, myTransform.position));
						}); 
				}
	}
	private void TargetEnemy(){
		if (selectedTarget == null) {
				SortTargetsByDistance ();
				selectedTarget = targetsList [0];
			} else {
			int index =targetsList.IndexOf(selectedTarget);
				if(index < targetsList.Count -1){
				index++;
				}else {
				index = 0;
				}
			DeselectTarget();
			selectedTarget = targetsList[index];
			}
		SelectTarget();
	}
	//indicates which target you have selected ( next 2)
	private void SelectTarget(){
		if (selectedTarget != null) {
						selectedTarget.renderer.material.color = Color.green;
		}
	}
	public void DeselectTarget(){
		selectedTarget.renderer.material.color = Color.red;
		selectedTarget = null;
	}
	void Update () {
		if (Input.GetKeyDown (KeyCode.Tab)) {
			TargetEnemy();		
		}
	}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Gouloriginal : MonoBehaviour {
	public GoulBuffs goulBuffs;
	public Controller2D controller2D;
	public Enemy2D enemy;
	public EnemyManager enemyManager;
	public Transform target;
	public PlayerPetTarget playerPetTarget;
	public Transform player;
	public float moveSpeed;
	private Transform goul;
	public int idleDistance = 1;
	public int enemyMaxDistance = 20;
	public int enemyMinDistance = 2;
	public float ddTime = 120;
	int goulDamage2;
	public float buffCoolDown;
	int doubbleDamageMultiplyer = 2;
	//attack vars
	public float attackRange;
	float attackRate = 1;
	float coolDown = 1;
	public int goulDamage;
	public bool enemyDied; 

	//12+ hours on this fucking script...
	void Awake(){
		goulDamage2 = goulDamage;
		goul = transform;
		playerPetTarget = GameObject.Find ("Player").GetComponent<PlayerPetTarget> ();
		goulBuffs = GameObject.Find ("Player").GetComponent<GoulBuffs> ();
		target = null;

	}
	void Start () {
		GameObject po = GameObject.FindGameObjectWithTag("Player");
		player = po.transform;
	}
	void Update (){ 
		if(buffCoolDown <= Time.time){
			goulDamage = goulDamage2;
		}
		Vector3 theScale = transform.localScale;
		theScale.x *= -1;
		transform.localScale = theScale;
		target = playerPetTarget.target;

	}
	void FixedUpdate () {
		if( target != null  Vector3.Distance (goul.position, target.position) < attackRange){
			if (Time.time >= coolDown){
					GoulAttack();
					coolDown = Time.time + attackRate;
				}
		}
		if (target == null || Vector3.Distance (goul.position, target.position) > enemyMaxDistance){
			if (Vector3.Distance (goul.position, player.position) > idleDistance) {
				if (player.position.x < goul.position.x) {
						goul.position -= goul.right * moveSpeed * Time.deltaTime; // player is left of goul, move left
				} else if (player.position.x > goul.position.x) {
						goul.position += goul.right * moveSpeed * Time.deltaTime; // player is right of goul, move right
					  }
				}
		}else if (target != null) {
			if (Vector3.Distance (player.position, target.position) < enemyMaxDistance  Vector3.Distance (goul.position, target.position) > enemyMinDistance) {
					if (target.position.x < goul.position.x) {
						goul.position -= goul.right * moveSpeed * Time.deltaTime; // target is left of goul, move left
					} else if (target.position.x > goul.position.x) {
						goul.position += goul.right * moveSpeed * Time.deltaTime; // target is right of goul, move right
					}
			}
		}
		Debug.DrawLine(player.position, goul.position, Color.yellow);
		if (target != null) {
						Debug.DrawLine (target.position, goul.position, Color.green);
		}
	}


	private void GoulAttack(){
				//find target with tag
		if (target != null  target.gameObject.tag == "Enemy") {
								//send damage call to enemy script
								target.gameObject.SendMessage ("EnemyDamaged", goulDamage, SendMessageOptions.DontRequireReceiver);
		}
	}
	public void DoubleDamage(){
		goulDamage = doubbleDamageMultiplyer * goulDamage2;
		buffCoolDown = Time.time + ddTime;
		Debug.Log (Time.time);
	}
}

Whoa that’s a lot of code to digest.

The quickest thing I can see with the least amount of changing code is in your Targeting script. I’m not sure what you want the player to do to activate the buff, in this example they just press the ‘B’ key. B for Buff. =)

void Update () {
  if (Input.GetKeyDown (KeyCode.Tab)) {
    TargetEnemy();
  }

  // New code here.
  if (Input.GetKeyDown(KeyCode.B)) {
    if (selectedTarget != null) {
      Gouloriginal foundTheGoul = selectedTarget.GetComponent<Gouloriginal>();
      if (foundTheGoul != null) { foundTheGoul.DoubleDamage(); }
    }
  }
}

Generally it’s a good idea to have a reference to the monobehaviour script or component instead of the GameObject. It makes more sense what the reference is for when you have an object of type Goul instead of a GameObject which could be anything.

thank you. just to clarify.

Gouloriginal foundTheGoul = selectedTarget.GetComponent<Gouloriginal>();

means the script is stored in a variable foundTheGoul and can be used to call functions like i would if i did a gameobject.Find correct?:smile:

Well in that code, foundTheGoul only exists inside your if block. If you declare Gouloriginal foundTheGoul; as a field in your class, like enemyManager or playerPetTarget, then you can just call foundTheGoul.SomeMethod() without having to find the gameobject and getting the component every time.

like this?

public Gouloriginal foundTheGoul;

void Awake(){
foundTheGoul = selectedTarget.GetComponent<Gouloriginal>();
}

I tried doing this yesterday, but it wouldn’t work for some reason. Monodevelop made me typecast it, then proceeded to tell me it was impossable.

Yeah, that looks right to me! There are a few different forms of GetComponent. The form of GetComponent with the angle brackets will automatically return the type inside the angle brackets, or null if the component can’t be found.

you are my new favorite person, thank you for taking the time to help me understand.