the code is not working on the GameObject
public class EnemyMovement : MonoBehaviour
{
public int rotateSpeed = 1;
public int movementSpeed = 1;
private Transform myTransform;
public Transform target;
// Start is called before the first frame update
void Start()
{
GameObject go = GameObject.FindGameObjectsWithTag("Player");
target = go.transform;
myTransform;
}
// Update is called once per frame
void Update()
{
Rotate();
}
void Rotate ()
{
Debug.DrawLine(myTransform.position, target.position, Color.red);
}
}
the error goes here
GameObject go = GameObject.FindGameObjectsWithTag("Player");
target = go.transform;
GameObject.FindGameObjectsWithTag("Player") returns an array of objects with type GameObject: See the documentation. Since your GameObject go is not an array, but a single GameObject, you're getting an error saying the compiler can't implicitly convert GameObject[] to GameObject.
If you only need one object, you may be looking for GameObject.FindWithTag which is called like this:
GameObject go = GameObject.FindWithTag("Player");
Related
public class move : MonoBehaviour
{
Animator animator;
bool dirToRight = true;
Rigidbody2D rigidbody;
public float heroSpeed;
bool onGround;
public Transform groundTester;
public float radius;
public LayerMask layerMask;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
rigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
onGround = Physics2D.OverlapCircle(groundTester.position, radius, layerMask);
}
}
I dont understand why bool "onGround" field not show error message, its bool type not Collider2d, the Physics2D.OverlapCircle() return Collider2D object not bool...... why please explain this magic for me....
Physics2D.OverlapCircle returns a Collider2D which is a Behaviour which is a Component which is a UnityEngine.Object which has an implicit bool operator
Does the object exist?
it basically return the same as
onGround = Physics2D.OverlapCircle(groundTester.position, radius, layerMask) != null;
I believe, it's synthetic sugar or shorthand for if(onGround) or if(onGround != null).
I am new at game dev, and I have question, I have my enemies prefabs, and enemy script, contains
public Transform player;
So Instead of every time putting my player into that 'slot', I want to make, script will be finding my player, I tried
private Transform player = GameObject.Find("player")
but it shows error
Here is the full script
public class Enemies : MonoBehaviour
{
public Transform player = GameObject.Find("Player");
private Rigidbody2D rb;
private Vector2 movement;
public float speed = 5f;
public int health;
// Start is called before the first frame update
void Start()
{
rb = this.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
Vector2 direction = player.position - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
rb.rotation = angle;
direction.Normalize();
movement = direction;
}
private void FixedUpdate()
{
Move(movement);
}
void Move(Vector2 direction)
{
rb.MovePosition((Vector2)transform.position + (direction * speed * Time.deltaTime));
}
private void OnMouseDown()
{
health = health - 1;
if(health <= 0)
{
Destroy(gameObject);
}
}
}
First of all you can't use Find in a static context. (Which is probably the error you are referring to.)
It goes a bit deeper into how c# works but in simple words: The class fields are all initialized even before the constructor is executed and thus at a moment when there still is no instance.
Secondly: GameObject.Find returns a GameObject not a Transform.
So if anything it would probably rather be
// Best would still be to drag this in if possible
[SerializeField] private Transform player;
void Start()
{
if(!player) player = GameObject.Find("Player").transform;
rb = this.GetComponent<Rigidbody2D>();
}
In general I always recommend to not use Find at all if anyhow possible. It is basically just a more expensive way of using some static or manager/provider based code
This has been annoying me for a while and I can't find a solution. Only ground3 moves while the other 2 stay in place. Im using unity and doing a 2d project.
Code:
using System.Collections.Generic;
using UnityEngine;
public class GroundMovement : MonoBehaviour
{
public float globalspeed;
public GameObject Ground1;
public float Ground1Speed;
Rigidbody2D rb1;
public GameObject Ground2;
public float Ground2Speed;
Rigidbody2D rb2;
public GameObject Ground3;
public float Ground3Speed;
Rigidbody2D rb3;
// Start is called before the first frame update
void Start()
{
rb1 = Ground1.GetComponent<Rigidbody2D>();
rb2 = Ground1.GetComponent<Rigidbody2D>();
rb3 = Ground1.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
rb1.velocity = new Vector2(globalspeed + Ground1Speed, 0);
rb2.velocity = new Vector2(globalspeed + Ground2Speed, 0);
rb3.velocity = new Vector2(globalspeed + Ground3Speed, 0);
}
}
The problem is in the Start() Method, when you assigned the rigidbodies, you assigned all of them to the rigidbody in the Ground1 GameObject, the method should be like this:
void Start()
{
rb1 = Ground1.GetComponent<Rigidbody2D>();
rb2 = Ground2.GetComponent<Rigidbody2D>();
rb3 = Ground3.GetComponent<Rigidbody2D>();
}
I just recently got into Unity 3D and currently working on one of my first own projects. For the game im making, I need a spawner function, that respawns a clone of the enemy as soon as the enemy falls off the platform. This is the code I have right now:
using UnityEngine;
public class spawner : MonoBehaviour
{
public GameObject enemyPrefab;
public float spawnHeight = 0.75f;
// Start is called before the first frame update
void Start()
{
spawnEnemy();
}
// Update is called once per frame
void Update()
{
if (enemyClone.transform.position.y < -10)
{
Destroy(enemyClone);
spawnEnemy();
}
}
public void spawnEnemy()
{
var enemyPosition = new Vector3(Random.Range(-5, 5), spawnHeight, Random.Range(-5, 5));
var enemyClone = Instantiate(enemyPrefab, enemyPosition, Quaternion.identity);
}
}
The function spawnEnemy itself works fine, since it creates an enemy on game start, tho further enemies aren't spawned. I get the message: "Assets\spawner.cs(21,21): error CS0103: The name 'enemyClone' does not exist in the current context".
I do see why I get the message, don't know how to make enemyClone globally available however.
Thanks to everybody in advance,
bezunyl
In the spawnEnemy() function, you say var enemyClone = Instantiate(...);. enemyClone is a local variable that can only be used within the spawnEnemy function, or at least that's how you've written it.
If you want to use the enemyClone outside of the spawnEnemy function, you need to declare the enemyClone variable outside of the function. (The example below will work if you DON'T want enemyClone to be accessible to other GameObjects)
using UnityEngine;
public class spawner : MonoBehaviour
{
public GameObject enemyPrefab;
public float spawnHeight = 0.75f;
private GameObject enemyClone //Added to allow enemyClone to be used anywhere in the class
// Start is called before the first frame update
void Start()
{
spawnEnemy();
}
// Update is called once per frame
void Update()
{
if (enemyClone.transform.position.y < -10)
{
Destroy(enemyClone);
spawnEnemy();
}
}
public void spawnEnemy()
{
var enemyPosition = new Vector3(Random.Range(-5, 5), spawnHeight, Random.Range(-5, 5));
enemyClone = Instantiate(enemyPrefab, enemyPosition, Quaternion.identity);
}
}
Now if you want enemyClone to be accessible by other GameObjects, then you'll want to make the enemyClone variable public instead of private. If you don't want it to show up in the inspector, add [HideInInspector] above the declaration of enemyClone, as shown below:
[HideInInspector]
public GameObject enemyClone;
Your issue is based on scope. You might want to research it, it's important to know.
The scope of a variable determines its visibility to the rest of a program.
http://www.blackwasp.co.uk/CSharpVariableScopes.aspx
http://www.informit.com/articles/article.aspx?p=1609145&seqNum=4
Spawning GameObject on demand is expensive. Instead of spawning it everytime, you should pool the GameObject.
public class Spawner : MonoBehaviour {
public Enemy enemyPrefab;
public List<Enemy> enemyPool;
public const SPAWN_HEIGHT = 0.75f;
// Start is called before the first frame update
void Start()
{
enemyPool = new List<Enemy>();
spawnEnemy();
}
// Update is called once per frame
public void Despawn(Enemy deadEnemy)
{
deadEnemy.gameObject.SetActive(false);
enemyPool.Add(deadEnemy);
}
public void spawnEnemy() {
Enemy newEnemy;
if (enemyPool.Count > 0) {
newEnemy = enemyPool[0];
enemyPool.Remove(0);
} else {
newEnemy = Instantiate(enemyPrefab);
}
newEnemy.Init(this);
newEnemy.position = new Vector3(Random.Range(-5, 5), SPAWN_HEIGHT, Random.Range(-5, 5));
newEnemy.gameObject.SetActive(true);
}
}
public class Enemy : MonoBehaviour {
private Spawner spawner;
private const float DEATH_POSITION_Y = -10;
public void Init(Spawner spawner) {
this.spawner = spawner;
}
void Update() {
if (transform.position.y < DEATH_POSITION_Y) {
spawner.Despawn(this);
}
}
}
I checked this code with a friend that has a better knowledge of Unity, but we can't find the problem.
Basically, Unity says that i can't parent a prefab, but i'm trying to change the parent of an instanced object, not the prefab.
I can't understand the error (but I think that it's in the Update method)
public GameObject[] Weapons;
public float projectileSpeed;
public float bulletTime;
public Rigidbody bullet;
private bool canShoot = true;
private float t = 0f;
private int actualBullets;
private GameObject actualWeapon;
private void Update()
{
t += Time.deltaTime;
if (actualWeapon != null)
return;
actualWeapon = GameObject.Instantiate(Weapons[0], gunPosition.position, gunPosition.rotation) as GameObject;
actualWeapon.transform.parent = GameManager.instance.player.transform;
}
public virtual void Fire()
{
if (canShoot)
{
actualBullets--;
var nBullet = GameObject.Instantiate(bullet, bulletSpawn.position, Quaternion.identity) as Rigidbody;
nBullet.AddForce (new Vector3(Vector3.forward.x, Vector3.forward.y, projectileSpeed));
canShoot = false;
}
else if (t > bulletTime)
(canShoot, t) = (true, 0);
}
Your problem is that
actualWeapon.transform.parent = GameManager.instance.player.transform;
is trying to get a parent that is not instantiated. You need to go to the GameManager and actually instantiate the player GameObject. Then you can keep a reference to the Player and make weapons children of the Player.
In my case, when developing Glitch Garden in Unity 5.5
private void Fire (){
GameObject newProjectile = Instantiate(projectile) as GameObject;
newProjectile.transform.parent = projectileParent.transform;
newProjectile.transform.position = gun.transform.position;
}
solved by Instantiate prefab projectileParent:
private void Fire (){
GameObject newProjectile = Instantiate(projectile) as GameObject;
newProjectile.transform.parent = Instantiate(projectileParent).transform;
newProjectile.transform.position = gun.transform.position;
}
Then, It caused another problem that is multiple projectiles. Finally,
I removed that line and it worked with following code:
private void Fire (){
GameObject newProjectile = Instantiate(projectile) as GameObject;
newProjectile.transform.position = gun.transform.position;
}
Above solution is a temp solution. Finally next video it will be fixed and current code is as follows:
public class Shooter : MonoBehaviour {
public GameObject projectile;
public GameObject gun;
private GameObject projectileParent;
void Start ()
{
projectileParent = GameObject.Find ("Projectiles");
if (!projectileParent) {
projectileParent = new GameObject();
projectileParent.name = "Projectiles";
}
}
private void Fire (){
GameObject newProjectile = Instantiate(projectile) as GameObject;
newProjectile.transform.parent = projectileParent.transform;
newProjectile.transform.position = gun.transform.position;
}
}