Instantiate a script into an instantiated prefab
Hello, I have a prefab called 'Enemy' and I wanted to instantiate it with an existing script as a new script for new variables ! Like instantiate the script into the instance of the 'Enemy' to acces new variables !
I tried to found the answer but that takes me one day of time...! I code in C#
Thanks to everyone in advance ! :)
Answer by Voyder_Rozann · Feb 18, 2017 at 05:40 PM
Thanks to @UnityCoach for helping me through this !!!
Here's my 2 scripts :
Bullet Script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
public float damage = 0.000092f;
private static int numberOfEnemyCollisions;
// use OnEnable to reset values, if you come to use some Object Pooling as Awake and Start will only ba called once
private void OnEnable()
{
damage = 0.000092f;
numberOfEnemyCollisions = 0;
}
public void OnTriggerEnter2D(Collider2D Col)
{
if (Col.tag == "Enemy" || Col.tag == "Enemy2")
{
numberOfEnemyCollisions += 1;
Col.gameObject.SendMessage("ApplyDamage", damage, SendMessageOptions.RequireReceiver); // send a message to the enemy gameobject that has an ApplyDamage (float damage) method
damage /= 2.25f; // divide the damage every time you hit
if (numberOfEnemyCollisions == BulletPenetration.NumOfCol)
{
Destroy(gameObject, 0.1f);
numberOfEnemyCollisions = 0;
}
// destroy the bullet if its damage has come under a given threshold
}
if (Col.tag == "Wall")
{
Destroy(gameObject);
}
}
IEnumerator SetTo0()
{
yield return new WaitForSeconds(1);
}
}
Enemy script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Enemy : MonoBehaviour
{
public float health = 0.0003f;
public Slider slidemyins;
public float EnemyLifeMAX;
// damage property to handle damage and destruction
private float _damage;
public float Damage
{
get { return _damage; }
set
{
if (value != _damage)
{
_damage = value;
if (_damage > health)
Destroy(gameObject); // destroy when damage reaches a critical level
}
}
}
// messages can be private, just like other builtin messages like Start and Update
private void ApplyDamage(float damage)
{
Damage += damage;
}
private void Start()
{
slidemyins = GetComponentInChildren<Slider>();
gameObject.GetComponent<Enemy>().EnemyLifeMAX = 0.0003f;
gameObject.GetComponent<Enemy>().health = 0.0003f;
}
private void Update()
{
slidemyins.GetComponent<Slider>().maxValue = EnemyLifeMAX;
slidemyins.GetComponent<Slider>().value = _damage;
}
}
Answer by UnityCoach · Feb 18, 2017 at 09:17 AM
If you instantiated an object that already has the script, you can get it with GetComponent. Like :
public Stuff InstantiateNewStuff (Stuff stuff)
{
GameObject g = Instanciate (stuff.gameObject);
return g.GetComponent<Stuff>();
}
If the game object doesn't have it, you can simply add it :
GameObject newGameObject = Instanciate (prefabReference);
newGameObject.AddComponent<Stuff>();
@UnityCoach I've tried that ! But what I wanted is to instantiate the script itself ! I've tried too to make multiple scripts with the same components of my first script... But that did not work at all !
You can instantiate the script itself, by simply allocating one like Stuff stuff = new Stuff ();
but you won't be able to add it to a GameObject as AddComponent doesn't take an instance for parameter, so it'll be useless. Usually you add the component and modify its values right after, like :
Stuff stuff = newGameObject.AddComponent<Stuff>();
stuff.myVar = value;
Can you tell a little more on what you want to achieve?
Here's some sample code that will help you architecture this :
public class Bullet : $$anonymous$$onoBehaviour
{
public float damage = 10f;
private int numberOfEnemyCollisions;
// use OnEnable to reset values, if you come to use some Object Pooling as Awake and Start will only ba called once
private void OnEnable ()
{
damage = 10;
numberOfEnemyCollisions = 0;
}
public void OnTriggerEnter2D (Collider2D Col)
{
if (Col.tag == "Enemy" || Col.tag == "Enemy2")
{
Col.gameObject.Send$$anonymous$$essage ("ApplyDamage", damage, Send$$anonymous$$essageOptions.RequireReceiver); // send a message to the enemy gameobject that has an ApplyDamage (float damage) method
damage /= 3; // divide the damage every time you hit
if (damage <= 1)
Destroy (gameObject); // destroy the bullet if its damage has come under a given threshold
}
if (Col.tag == "Wall")
{
Destroy(gameObject);
}
}
}
public class Enemy : $$anonymous$$onoBehaviour
{
public float health = 100f;
// damage property to handle damage and destruction
private float _damage;
public float Damage
{
get { return _damage; }
set
{
if (value != _damage)
{
_damage = value;
if (_damage > health)
Destroy (gameObject); // destroy when damage reaches a critical level
}
}
}
// messages can be private, just like other builtin messages like Start and Update
private void ApplyDamage (float damage)
{
Damage += damage;
}
}
How can I accept your response ?... Because I found what I needed !!! Thank you !
Answer by Voyder_Rozann · Feb 18, 2017 at 01:37 PM
@UnityCoach In this case, i want my bullet 'penetration' to, everytime OnTriggerEnter2D collide an enemy, divide the Damage do to the enemy by 2 every next enemy the bullet collide ! But when I shoot, the bullet appear, the bullet do damage, But right next, I shoot the second bullet that takes the count of my first bullet
Here's my Bullet script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shoot2 : MonoBehaviour
{
public static float ColliderNum;
public float ActualCount;
public static float DivDamage;
private void Start()
{
DivDamage = 1f;
ColliderNum = 0f;
}
public void OnTriggerEnter2D(Collider2D Col)
{
if (Col.tag == "Enemy" || Col.tag == "Enemy2")
{
DivDamage += 1f;
ColliderNum += 1f;
if (ColliderNum == BulletPenetration.NumOfCol)
{
DivDamage = 1f;
ColliderNum = 0f;
Destroy(gameObject);
}
}
if (Col.tag == "Wall")
{
DivDamage = 1f;
ColliderNum = 0f;
Destroy(gameObject);
}
}
}
Here's my Bullet Penetration Script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BulletPenetration : MonoBehaviour
{
public float PRICE4;
public float HM4;
public Text text4;
public Button bouton4;
public Color colorgreen;
public static float NumOfCol;
private void Start()
{
NumOfCol = 1f;
PRICE4.ToString("n2");
colorgreen.g = 0.5f;
bouton4.image.color = Color.red;
PRICE4 = PlayerPrefs.GetFloat("PRICE4", 0.89f);
HM4 = PlayerPrefs.GetFloat("HM4", 0f);
}
private void OnDestroy()
{
PlayerPrefs.SetFloat("PRICE4", PRICE4);
PlayerPrefs.SetFloat("HM4", HM4);
}
private void Update()
{
if (EUROSARGENT.EUROS <= PRICE4)
{
bouton4.image.color = Color.red;
}
else if (EUROSARGENT.EUROS >= PRICE4)
{
bouton4.image.color = colorgreen;
}
text4.text = ("Bullet P Lenght" + ("\n€=" + PRICE4) + ("\nYou Bought " + HM4));
}
public void Buy004()
{
if (EUROSARGENT.EUROS >= PRICE4)
{
EUROSARGENT.EUROS -= PRICE4;
PRICE4 = Mathf.Round(PRICE4 * 110f) / 100f;
HM4 += 1f;
NumOfCol += 1;
}
}
}
And Here's my EnemySpawn script :
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EnemySpawn : MonoBehaviour
{
public Slider slidemyins;
public float speed;
public float EnemyLifeMAX;
public float EnemyLife;
public float EnemyLifeODD;
public float DoPlayerDamage;
public static float DoEnemyDamage;
public float bulletdamage;
IEnumerator PlayerDamage()
{
yield return new WaitForSeconds(0.94f);
PlayerShoot.PlayerHealth -= DoPlayerDamage;
yield return PlayerDamage();
}
private void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "Bullet")
{
EnemyLifeODD -= bulletdamage / Shoot2.DivDamage;
}
if (col.tag == "Player")
{
gameObject.GetComponent<EnemySpawn>().speed = 0.0001f;
StartCoroutine(PlayerDamage());
}
else
{
StopCoroutine(PlayerDamage());
gameObject.GetComponent<EnemySpawn>().speed = 50f;
}
}
void Start()
{
speed = 50f;
DoPlayerDamage = 0.00001f;
EnemyLifeMAX = 0.0003f;
EnemyLife = 0.0003f;
EnemyLifeODD = 0.0003f;
slidemyins.GetComponent<Slider>();
}
void Update()
{
bulletdamage = BulletDamage.DEALENEMYDAMAGE;
slidemyins.GetComponent<Slider>().maxValue = EnemyLifeMAX;
slidemyins.GetComponent<Slider>().value = EnemyLifeODD;
Vector2 Position = transform.position;
Position = new Vector2(Position.x - speed * Time.deltaTime, Position.y);
transform.position = Position;
if (gameObject.GetComponent<EnemySpawn>().EnemyLifeODD <= 0)
{
gameObject.SetActive(false);
EUROSARGENT.GetTheMoney();
}
}
}
I'll post an answer when I figure it out. In the meantime, I'd say you don't want to call GetComponent within an Update, it has a bit of a cost on performance.
Ok thank you, I didn't knew that GetComponent on a Update function will cost performance ! I will fix my scripts !
Your answer
Follow this Question
Related Questions
Instantiate a prefab and assign it's values 1 Answer
Basic Unity: Can someone explain the referencing and instantiation process? 1 Answer
Instantiate prefab if no prefab exists at location 1 Answer
If instantiate prefab is selected how can i change the color? 1 Answer
Prefab destroyed upon instantiation 0 Answers