I´m trying to instantiate a clone of a prefab. I pass as parameter the prefab to clone, the position to put it and the rotation.
The problem is that Unity don't put the clone as the desired position. Any ideas?
using UnityEngine;
using System.Collections;
public class EnemyGenerator : MonoBehaviour
{
public GameObject enemy;
void Start()
{
Instantiate(enemy, new Vector3(30, 30, 30), Quaternion.identity);
}
}
Related
I want to have clones of a certian gameobject face the direction of the player at an angle, for example, if there were enemy clones with guns I would want the guns to face the players position. Any ideas how to do?
This is even harder to achieve because since it's a clone you cannot access other GameObjects.
Script:
public class GunProperties : MonoBehaviour
{
public Transform target;
void Update()
{
transform.LookAt(target);
}
}
You could initialize the clones with some values when you instantiate it.
Example:
In this case I have a GameManager that keeps track on the player, and passes the reference over when an enemy is spawned.
public class GameManager : MonoBehaviour
{
public Transform player;
public Enemy enemyPrefab;
void SpawnEnemy() {
var enemy = Instantiate<Enemy>(enemyPrefab);
enemy.Init(player)
}
}
public class Enemy : MonoBehaviour {
private GunProperties gun;
public void Init(Transform target) {
gun.target = target;
}
}
You could also reverse it by making the GameManager a singleton and having the enemies find the player on awake by using GameManager.Instance.player
I'm using a namespace to instantiate a prefab in my game however unity thinks that the prefab is not a GameObject and returns the NullReferenceException error
I've linked the Prefab, properly in the GameObject that holds the script. This is the code that I currently have in Visual Studio but I also tried various forms of the code, they are what follows the first lines of code
public GameObject Prefab;
public void OnAppear(){
GameObject spawn = Instantiate(Prefab, Spawnpoint.position, Spawnpoint.rotation);
spawn.transform.parent = Spawnpoint.transform;}
V1
var spawn = Instantiate(Prefab, Spawnpoint.position, Spawnpoint.rotation);
V2
var spawn = Instantiate(Prefab, Spawnpoint.position, Spawnpoint.rotation) as GameObject;
Entire script:
namespace AugReal
{
public class StartAll : MonoBehaviour
{
public Transform Spawnpoint;
public GameObject Prefab;
public void OnAppear()
{
GameObject spawn = Instantiate(Prefab, Spawnpoint.position, Spawnpoint.rotation);
spawn.transform.parent = Spawnpoint.transform;
}
public void OnDisappear()
{
Debug.Log("You lose");
}
}
}
Inspector:
Try the following code instead:
You do not need to create a public reference to the transform that this script is attached to. Since the script is a monobehaviour, you can directly access this via this.transform
Rather than setting the parent explicitly after instantiating, consider usign the Instantiate method with the parent override.
(I have also change the casing on your property "Prefab". It doesn't affect the code, but standard is to keep property names camelCase to distinguish them from the PascalCased class types.)
namespace AugReal
{
public class StartAll : MonoBehaviour
{
public GameObject prefab;
public void OnAppear()
{
GameObject spawn = Instantiate(prefab, this.transform);
}
public void OnDisappear()
{
Debug.Log("You lose");
}
}
}
I am learning Unity3D from zero. I found that we can access the GameObject to which a script declaring a derived class of MonoBehaviour is attached as follows.
via this
via gameObject
via private field with [SerializedField] attribute.
Trivial Code
using UnityEngine;
public class Ball : MonoBehaviour
{
[SerializeField]
private GameObject ball;
void Update()
{
Vector3 force = new Vector3
{
x = 5 * Input.GetAxis("Horizontal"),
y = 0,
z = 5 * Input.GetAxis("Vertical")
};
//gameObject.GetComponent<Rigidbody>().AddForce(force);
//this.GetComponent<Rigidbody>().AddForce(force);
ball.GetComponent<Rigidbody>().AddForce(force);
}
}
Question
Among those three, I only want to know when we need to choose this instead of gameObject and also the reverse?
They are different things!
When you are using this, you are referencing the This keyword, which in this case is talking about the MonoBehaviour you are writing.
When you use gameObject, you are talking about the gameobject that the behaviour you are writing is contained. This gameObject can contain othe MonoBehaviours.
So for example, if your MonoBehaviour has an property you can reference it with "this". And if the gameobject has a Physics Component, you can use GetComponent to access it.
I am using an animated sprite to collide and delete an enemy sprite. The enemy sprite disappears when it hits my floor (sprite) also. (All have rigidbody2D). How do I get the enemy sprite to ignore the floor and everything else except the animated sprite?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Collision : MonoBehaviour
{
void Start()
{
}
void Update()
{
}
void OnCollisionEnter2D()
{
if (gameObject.tag.Equals("Enemy"))
{
Destroy(gameObject);
}
}
}
Go to Edit > Project Settings > Physics (or Physics2D) and edit the Layer Collision Matrix:
So I have an enemy spawner with a method to instantiate prefabs working just fine. Simplified:
public class EnemySpawner : MonoBehaviour {
public GameObject EnemyPrefab;
public void setEnemies()
{
Instantiate (EnemyPrefab, enemyPos, rotation);
}
void Start()
{
setEnemies();
}
}
This works fine. But it doesnt work when I call it from a different script:
public class Player : MonoBehaviour {
public EnemySpawner enemyspawner;
void Update(){
if (Input.GetMouseButtonDown (0))
{
enemyspawner= new EnemySpawner();
enemyspawner.setEnemies();
}
}
I keep getting this error:
ArgumentException: The prefab you want to instantiate is null.
What am I doing wrong?
Edit:
So I figured that I could not create a Monobeaviour by using the New keyword .I changed it to:
enemyspawner = gameObject.AddComponent<EnemySpawner> ();
enemyspawner.setEnemies();
But that still wont work.
I just read your comment about changing:
new to enemyspawner = gameObject.AddComponent<EnemySpawner>();
However, you did not properly solve the problem, you only made a workaround that won't work because your prefab, public GameObject EnemyPrefab;, won't be set.
With your new code gameObject.AddComponent<EnemySpawner>(); You are attaching a script to the Player GameObject, this will bring you problems in the future.
My Suggestion
Create an Empty GameObject and attach EnemySpawner to it and name it EnemySpawnerObj.
Then to call the function setEnemies() from another class you do this:
EnemySpawner spwner = GameObject.Find("EnemySpawnerObject").GetComponent<EnemySpawner>();
spwner.setEnemies();
So what you are doing is looking through your scene for the GameObject named EnemySpawnerObject then you get the component named EnemySpawner and then you can call that class instance.