So I'm writing a script for respawning objects for a 2d game on unity, however whenever i try to call the object that is to respawn, it says that the object is either a method or statement. I feel like I've made a mistake somewhere. Please help correct me where im wrong. This is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public GameObject spike;
public class Spikegenerator: MonoBehaviour
{
void Start()
{
for (int i = 0; i < 10; i++)
{
float spawnY = Random.Range
(Camera.main.ScreenToWorldPoint(new Vector2(0, 0)).y,
Camera.main.ScreenToWorldPoint(new Vector2(0, Screen.height)).y);
float spawnX = Random.Range
(Camera.main.ScreenToWorldPoint(new Vector2(0, 0)).x,
Camera.main.ScreenToWorldPoint(new Vector2(Screen.width, 0)).x);
Vector2 spawnPosition = new Vector2(spawnX, spawnY);
Instantiate(spike, spawnPosition, Quaternion.identity);
// the gameobject is 'spike'
}
}
}'''
The spike variable u are providing doesn't exist yet in the code.
Make sure you add public GameObject spike
Inside your class and insert the prefab spike via the editor.
Make sure you added spike on the inspector of your GameObject.
Related
I'm new, and I've got hard time to respawn my AI (right now he just a cube that follow my player) after he been destroy. I believe its because the script sits on the object that get destroyed. but what I need to do to respawn it?
(although I'm sure my respawn code is not good :\ (It's mobile-android project) )
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyTesting : MonoBehaviour
{
[SerializeField]
public GameObject player;
public GameObject enemy;
private Rigidbody body;
Vector3 accelerationDir;
// Use this for initialization
void Start()
{
body = GetComponent<Rigidbody>();
}
private void Update()
{
accelerationDir = Input.acceleration;
if (accelerationDir.sqrMagnitude>=5)
{
EnemyDead();
}
}
void EnemyDead()
{
Destroy(enemy);
Invoke("Respawn", 5);
}
void Respawn()
{
enemy = (GameObject)Instantiate(enemy);
enemy.transform.position = transform.position;
}
// Update is called once per frame
void FixedUpdate()
{
Vector3 toTarget = player.transform.position - transform.position;
float speed = 1.5f;
transform.Translate(toTarget * speed * Time.deltaTime);
}
}
Thanks very much!
I am supposing that your enemy GameObject is inside the scene holding your EnemyTesting MonoBehaviour instance (correct me if I'm wrong).
If this is the case, you cannot instantiate a gameObject that is destroyed.
As #derHugo pointed out, you should not use Destroy and Instantiate for your use case. It would be better to set inactive the enemy GameObject, move it to the position that you want, an (re)set it active. It will look like the enemy respawned.
If you want to dig the subject later, look at the object pooling game optimization pattern.
Otherwise, if you still want to use Instantiate for respawning, I would create a prefab of your enemy GameObject. The enemy GameObject referenced in the EnemyTesting field (in the Inspector view), would be your prefab from the project hierarchy instead of a GameObject inside the scene.
This way, you would be able to instantiate an enemy GameObject as many times as you want (and use it in other scenes!). Don't forget to hold a reference to the instantiated enemy GameObject so you can know which one you want to destroy. It would looke like this :
enemy = Instantiate(enemyPrefab, transform.position, transform.rotation);
You can replace transform with the transform of your choice, for example the transform of an empty enemyRespawnPoint GameObject in your Scene.
Do you see any error in the console ?
I'm a Unity beginner.
I have a problem with my script: in the picture above, Player item does not exist in Move script.
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float speed;
public Transform player;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
transform.Translate(x * speed * Time.deltaTime, y * speed * Time.deltaTime, 0);
Vector2 v2 = Camera.main.ScreenToWorldPoint(Input.mousePosition) - player.position;
player.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(v2.y, v2.x) * Mathf.Red2Deg);
}
}
I am not sure if I understand you right, but as this script is the script that belongs to the Player Gameobject, you don't need to specify "public Transform player".
The Gameobject class inherits from the Transform class, so it should work if you try:
Vector2 v2 = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(v2.y, v2.x) * Mathf.Red2Deg);
Maybe to make it more clear:
You don't need to have Player as an "item" that you pull into the according field in the inspector as it was the case if you relate to a gameobject which does not contain the "Move" script.
So, if you attach a script to a gameobject (in this case you attach the script to "Player"), then any methods you script, are directly affecting the gameobject the script belongs to.
E.g. try the following:
void Update() {
if(Input.GetKeyDown("space")) {
Destroy(gameObject);
}
}
You will see that the circle, which forms your player, will destroy itself when you hit the space bar. The parameter "gameObject" refers to the gameobject the script belongs to.
I hope that helps you to understand that you don't need to specify an extra GameObject that needs to be linked to the script, as long as the Gameobject you want to manipulate contains this script.
I'm writing a script in C# in Unity that essentially functions as a switch to turn gravity on or off for a 2D Rigidbody. When the game starts, gravity should be 0 for the Rigidbody. Then when the user taps the space bar, gravity is supposed to increase to 3 (which is does). Then, however, when the player collides with a gameObject labeled 'InvisGoal', the player should teleport to another location and then gravity should be 0 again. However, the player always falls after coming in contact with InvisGoal and teleporting and I can't figure out why. This is my first project in C# so sorry for any obvious errors.. The script is here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallLaunch : MonoBehaviour {
private Rigidbody2D myRigidBody;
public GameObject Ball;
// Use this for initialization
void Start ()
{
myRigidBody = GetComponent<Rigidbody2D> ();
GetComponent<Rigidbody2D>().gravityScale = 0f;
}
// Update is called once per frame
void Update ()
{
if (Input.GetButtonDown ("Jump"))
{
GetComponent<Rigidbody2D> ().gravityScale = 3f;
}
}
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "InvisGoal")
{
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
transform.position = new Vector3 (0.61f, 1.18f, 0f);
return;
}
}
}
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
This is likely what is causing the problem.
It sounds like the RigidBody2D you are referencing to in this line is not the same as the one you retrieved beforehand with GetComponent().
GetComponent returns the component of the GameObject you call it from. Therefore in the code I mentioned above,
Ball.gameObject.GetComponent<RigidBody2D>()
and
GetComponent<RigidBody2D>()
would give you an two different RigidBody2D component if the field Ball does not refer to the same GameObject your BallLaunch script is attached to.
[
Supposing BallLaunch script is attached to the Ball you want to set the gravity of (As picture above)
Simply change:
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
To
GetComponent<Rigidbody2D>().gravityScale = 0f;
Also, since you already referenced your RigidBody2D in your Start method to the field myRigidBody, you can replace all subsequent GetComponent with myRigidBody.
GetComponent<Rigidbody2D>().gravityScale = 0f;
To
myRigidBody.gravityScale = 0f;
I am currently working on a game prototype, this game would require to
spawn some GameObjects which I call "stars", all good with
instantiating, but when I try to delete them when there are to many
around it does not work, I am trying to put all instantiated
GameObjects in a list and then delete the last object from it when
the new one was instantiated. As you can see from the code, when 3
objects are spawned the script should delete one from the beginning
and spawn a new one in the same time.
Now, the problem is that I don't know what am I missing here, the code does not work and I don't know why. Please help me. Thank you!
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnStar : MonoBehaviour {
public float addedSpeed = -200f;
private GameObject spawned;
private float randomX;
public GameObject starToSpawn;
private List<GameObject> activeGO;
void Start ()
{
activeGO = new List<GameObject> ();
Invoke ("InstantiateStar", 2f);
}
// Update is called once per frame
void FixedUpdate ()
{
GetComponent<Rigidbody>().AddForce( new Vector3( 0f, addedSpeed, 0f));
}
void InstantiateStar ()
{
randomX = Random.Range (-3f, 3f);
GameObject GO;
GO = Instantiate (starToSpawn, new Vector3(randomX, 5f, 0f), transform.rotation) as GameObject;
activeGO.Add (GO);
if ( activeGO[0].transform.position.y < -2f)
{
DeleteActiveGO ();
}
}
void DeleteActiveGO ()
{
Destroy (activeGO [0]);
activeGO.RemoveAt (0);
}
}
I am back with an update. The problem was that I was trying to do 2 thing in one script...short story: To solve the problem I created an empty object in the scene, divided my script in 2 separated scripts, one that makes the spawned object move faster and one that is spawning the object, I put the script that moves the object on to the object that will be spawned and The other script on the empty GameObject that will spawn the "Stars" and it worked like a charm.
Thank you for all your answers!
here are the final scripts:
Spawning script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnStars : MonoBehaviour {
public GameObject[] starsToSpawn;
private List<GameObject> spawnedStars;
private float randomX;
void Start ()
{
spawnedStars = new List<GameObject> ();
InvokeRepeating ("SpawnStar", 0f, 3f);
}
void SpawnStar ()
{
randomX = Random.Range (-3, 3);
GameObject GO;
GO = Instantiate ( starsToSpawn[0], new Vector3 (randomX, 5f, 0f), transform.rotation);
spawnedStars.Add (GO);
if (spawnedStars.Count > 2 )
{
Destroy (spawnedStars [0]);
spawnedStars.RemoveAt (0);
}
}
}
Moving script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveStar : MonoBehaviour {
public float acceleration = -5f;
void FixedUpdate ()
{
GetComponent<Rigidbody>().AddForce( new Vector3( 0f, acceleration,0f));
}
}
Your code Invoke ("InstantiateStar", 2f); only call once.
You can change to InvokeRepeating("InstantiateStar",2f,2f );
The Code GetComponent<Rigidbody>().AddForce( new Vector3( 0f, addedSpeed, 0f)); seem like should attach to the Generate Gameobject.
Also note your delete condition.
good luck.
#Noobie: What you are trying to do is called Object Pooling. Your implementation is rather not correct.
It would be better for you to learn the same and implement.
Read more here: https://unity3d.com/learn/tutorials/topics/scripting/object-pooling
In my FPS Game, I am trying to make my player throw a grenade. I know there are similar questions like this, but the posts are old and they the answers did not help me at all. When I tried to make my grenade throw using the AddForce() method, the grenade merely spawned right in front of the player, like the AddForce() method was never called. The same happened when I set its velocity to a value. It seems like the grenade won't move at all! I have made sure that:
The grenade is NOT Kinematic
It doesn't work with both gravity on and off
No Positions/Rotations are frozen
There is a rigid body attatched
There isn't a character controller attached to the grenade
The mass is only one
My code is below:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Script : MonoBehaviour {
[SerializeField] GameObject grenade;
public int throwForce = 30;
Vector3 spawnPosition;
// Use this for initialization
void Start () {
instantiateVariables ();
}
void instantiateVariables(){
}
void throwGrenade(){
print (spawnPosition);
GameObject tempGrenade = (GameObject) Instantiate (grenade, spawnPosition, transform.rotation);
Vector3 direction = new Vector3(transform.forward.x, transform.forward.y, transform.forward.z );
Rigidbody rb = grenade.GetComponent<Rigidbody> ();
if (rb != null){
rb.velocity = direction.normalized * 10f;
Destroy (tempGrenade, 10);
}
else {
Debug.LogError ("There is no rigid body on your cube!");
}
}
// Update is called once per frame
void Update () {
spawnPosition = transform.forward + transform.position;
print (spawnPosition);
if (Input.GetMouseButtonDown (1)) {
throwGrenade ();
}
}
}
Inspector:
Shouldn't you store the tempGrenade's rigidBody Component in rb instead of grenade's rigidBody? I would recommend using tempGrenade's rigidBody and then modifying rb.velocity.
Like:
rb = tempGrenade.GetComponent<Rigidbody> ();
EDIT: Corrected the line of code by removing the velocity field