How to spawn objects in Unity? - c#

I am trying to build a flappy bird like game and I am trying to spawn enemy birds and gold coins so I have written the C# code and the made the prefabs, but when I run the bird and the coins are not respawning.
This is the respawn code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnPlayer : MonoBehaviour
{
public GameObject GameObjectToSpawn;
private GameObject Clone;
public float timeToSpawn = 4f;
public float FirstSpawn = 10f;
// Update is called once per frame
void Update()
{
FirstSpawn -= Time.deltaTime;
if (FirstSpawn <= 0f)
{
Clone = Instantiate(GameObjectToSpawn, gameObject.transform.localPosition, Quaternion.identity) as GameObject;
FirstSpawn = timeToSpawn;
}
}
}
screenshot of unity:
This where i am respawning the first enemy bird:

From your second screenshot it seems to be spawned but way off the screen! You can still see the tiny little island in the bottom left corner.
You thought seems to be that you have to spawn it in the Canvas pixel space using the spawn point's localPosition. But this is not the case since Instantiate places it into the scene root (without any parent) with absolute world-space position into the scene.
You should rather actually place the spawn point to the absolute world position where the spawn should happen and rather use
Clone = Instantiate(GameObjectToSpawn, transform.position, Quaternion.identity);
Btw no need for the as GameObject since Instantiate already returns the type of the given prefab.

Related

Untiy Health System

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveProjectile : MonoBehaviour
{
public Rigidbody2D projectile;
public float moveSpeed = 10.0f;
// Start is called before the first frame update
void Start()
{
projectile = this.gameObject.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
projectile.velocity = new Vector2(0,1) * moveSpeed;
}
void OnCollisionEnter2D(Collision2D col){
if(col.gameObject.name == "Enemy"){
gameObject.name == "EnemyHeart5".SetActive(false);
}
if(col.gameObject.name == "Top"){
DestroyObject (this.gameObject);
}
}
}
This is the code to my player projectile. On collision i tried to reference it to a game object i have called playerheart and it doesnt seem to work out the way i wanted it to.
Im trying to make a health system where if my bullet collides with the enemy game object the health would decrease by one. Im pretty new to Unity and im confused on how to target the hearts when the bullets collide.
I'm assuming "EnemyHeart5" is a GameObject inside Enemy as child gameobject. Correct?
Issue here is when the collision takes place, it recognize "Enemy" gameobject and won't have access to "EnemyHeart5" for disabling it. I'd suggest you to add simple EnemyManager script into your enemy which manages your enemy health and health related gameobject (ie. EnemyHearts which you are displaying). When collision takes place, access that EnemyManager component and change health value.
void OnCollisionEnter2D(Collision2D col){
if(col.gameObject.tag == "Enemy"){
col.gameObject.GetComponent<EnemyManager>().health =-1;
}
Now, in the update method of EnemyManager you check the health value and disable EnemyHealth5 component.
Also, use "tag" in collision instead of "name". name will create issues when you have multiple enemies in the game. Make sure you add tag in enemy gameobject if you are using it.
Hope this helps, let me know how it goes.

Bullets not showing in Game view

I am making a simple 2d shooter in unity. I have made a prefab for my weapons and a script to shoot. When I enter the game mode I can see the bullet objects being created, but the bullets don't show on the screen. When I pause it and enter the scene mode they show (most of the time) any idea what could be causing this??
Here is the various settings on my bullet :
Thanks in advance for your help
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour
{
//variable to handle what progectile to spawn
public GameObject projectile;
//from where does the bullet coem from
public Transform shotPoint;
//How much time should be taken between shots
public float timeBetweenShots;
//time to shoot another bullet
private float shotTime;
// Update is called once per frame
private void Update()
{
//Callculating the the current mouse position to the current weapon position
//Input.mouse position returns a screenpoint
Vector2 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = rotation;
//if the left mouse button is pressed
if(Input.GetMouseButton(0)){
//if the current time in the game is greater than the shot time
if (Time.time >= shotTime)
{
//shoot projectile
Instantiate(projectile, shotPoint.position, transform.rotation);
//recalculate shot time current time + time between shots
shotTime = Time.time + timeBetweenShots;
}
}
}
}
Check the order layer if you're by mistake not covering your bullets with the background image. Just make your bullet prefab layer higher then background equivalent.
Moreover, move the background node out of the scope of Player (currently you have it in the Player node), it should be equally set as your Main Camera and Player nodes in the tree. Then check the layering order and make sure order value in background is the lowest of all of your sprites.
Basically you are creating bullets inside of the weapon thats why you are not able to see your bullets. I create simple scene and adding sphere as a bullet then I realized sphere spawning in the gun(for me in the cube). If you will adding force everything will be okay.
Assume the shootPoint is somewhere over the gun barrel,
Instantiate(projectile, shotPoint.position, transform.rotation);
You should give them force,
GameObject projectile= Instantiate (prefab, position, rotation) as GameObject;
rb = projectile.GetComponent<Rigidbody>();
rb.AddForce (direction * speed);
Dont forget to add rigidbody to the bullet

Unity c# - unable to Spawn Prefabs on a NavMesh

I am trying to make a zombie wave game and current have a Prefab for my enemies. If I have the prefab be in the scene when I hit run, they are attached to the NavMesh and track the player perfectly. I want to achieve this but with the enemy being spawned from an empty GameObject so I can get the waves spawning in. I have achieved them Spawning but they have the error,
"SetDestination" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.AI.NavMeshAgent:SetDestination(Vector3)
EnemyAI:Update() (at Assets/Scripts/EnemyAI.cs:25)
Here is my EnemyAI Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
public float lookRadius = 10f;
Transform target;
NavMeshAgent agent;
public GameObject Player;
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
float distance = Vector3.Distance(Player.transform.position, transform.position);
if (distance <= lookRadius)
{
agent.SetDestination(Player.transform.position);
}
}
}
And my spawning script, which is attached to an empty game object,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawning : MonoBehaviour
{
public GameObject prefab;
public int CountofCubes;
private IEnumerator coroutine;
public float spawnRate;
IEnumerator Start()
{
while (true)
{
for (int i = 0; i < CountofCubes; i++)
{
Instantiate(prefab, new Vector3(Random.Range(-25.0f, 25.0f), 0.5f, Random.Range(-25.0f, 25.0f)), Quaternion.identity);
}
yield return new WaitForSeconds(spawnRate);
}
}
}
Any help would be great thanks!
I had the same issue and I don't have an explanation but only a workaround:
In the Start fucntion, I added:
navAgent = GetComponent<NavMeshAgent>();
navAgent.enabled = false;
// Invoke is used as a workaround for enabling NavMeshAgent on NavMeshSurface
Invoke("EnableNavMeshAgent", 0.025f);
And the EnableNavMeshAgent function is just :
private void EnableNavMeshAgent ()
{
navAgent.enabled = true;
}
If I set the invoke delay to a value less than 0.025 second the error keep going but for 0.025 I only have it twice and the behaviour is the one I wanted after that.
Some reasons this might happen:
The agent is not on level with any navmesh i.e. can be too far above or below. You want it to be "close to the NavMesh surface". Use raycasting on the floor to position the agent or add a rigidbody and drop it from above the floor. After you do this you might need to disable and enable the agent.
Moving the transform yourself rather than using Wrap function. There's property where you can check if the simulated and actual position are in sync.
Corrupted navmesh so you might need to re-bake it.
It is essentially trying to tell you your agent is not on the mesh so it cannot find a path. Try playing with where you're placing the agent.
I kind of remember running into a similar problem a while back and problem was I forgot to bake the NavMesh in Window > AI > Navigation. Just in case.

2D Polygon Collider not causing collisions with a 2d polygon collider

I am in the middle of working on a game, and I just started. I added in the map as a png and have been adding in colliders around the areas that I want to be impassable (it is a 2D platformer). I have an enemy already designed and added a 2DRigidBody component to it as it moves around, and started to use 2DBoxColliders as the colliders for the level, and my script that I have written:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Sexapus : MonoBehaviour {
public static int Velocity = 42;
public Rigidbody2D rb;
public Vector2 dir;
public Animator anim;
void Start () {
rb = GetComponent<Rigidbody2D>();
dir = new Vector2(1, 0);
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
rb.velocity = dir * Velocity;
anim.SetFloat ("Direction", dir.x);
}
void OnCollisionEnter2D (Collision2D col) {
dir = dir * -1;
}
//CHECK TASKS
}
Meant that the enemy would hit the side of a wall and then rotate and start going the other way. I realised with the size of my map that using multiple 2DBoxColliders (and when I say multiple I mean I would probably have to use over a hundred) was a very bad way of doing it. I have now started to use a 2DpolygonCollider for the map as well, but now the enemy doesn't collide with the sides of the wall and turn around, it just stays facing the same direction but doesn't move. Anyone know why?
You are using the same collider for the floor and the walls... So when you collide with the wall, and are already touching the floor, the OnCollisionEnter will not happen.
So, you do get the collision, hence the object cant move past the wall, BUT it's not a new collision!
Solution: Use a collider to the floor, and a different one to the walls, Edge colliders are good for this.

Killing one Enemy causes every enemy to disappear - C# Unity

I have a problem with a game that I'm creating in Unity. The player controls a character that is getting attacked by a horde of zombies. I've created a spawner for all the zombies and that works great, the only problem is that once the player kills one zombie all the zombies disappear from the gameworld. I've posted the enemy script that is attached to each zombie below. I can't work out why every zombie is destroyed instead of just the one that has been attacked. Any help would be great!
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
public static float Damage = 10.0f;
public static float Health = 10.0f;
public Transform target;
public float Speed;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//Destroy the enemy if it's health reaches 0
if(Health <= 0){
Destroy(this.gameObject);
Debug.Log ("Enemy Destroyed!");
}
//Constantly move the enemy towards the centre of the gamespace (where the base is)
float step = Speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}
The way the scene is set up is that I have an empty game object that contains a series of position objects and a spawner script that places the enemy sprite into the position object. This all seems to work fine but I can't find whats causing them to all disappear.
The problem is that you have declared Health as a static variable. This means Health will have the same value across all of your enemy instances. Declare health like this instead:
public float Health = 10.0f;
This way, each instantiated enemy will be able to have its own unique Health value.

Categories

Resources