0
votes

I'm having an issue instantiating Prefabs in Unity.

I'm working on a game where you have enemies moving towards you and you have to kill them. My original enemy game object moved towards the player with little to no problem, but the instantiations of that object wouldn't move.

To make matters more confusing, when I copied the game object and added it to the scene without instantiation, both game objects would move towards the player just fine.

Enemy script:

public class EnemieController : MonoBehaviour
{
    [SerializeField]
    float moveSpeed = 1;

    [SerializeField]
    private Rigidbody2D rb;
    public Transform player;
    public float health = 50;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        Debug.Log(player);
    }

    // Update is called once per frame
    void Update()
    {
        MoveTowardsPlayer();
    }

    void MoveTowardsPlayer()
    {
        Vector3 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        Vector2 direction = (player.position - transform.position).normalized;
        rb.velocity = new Vector2(direction.x * moveSpeed, direction.y * (moveSpeed * 1));

    }
}

Instantiation Code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using System;

[System.Serializable]
public class GameManagement : MonoBehaviour
{
    public GameObject circleEnemie;
    public Transform player;
    [SerializeField]
    float moveSpeed = 1;
    // Start is called before the first frame update
    void Start()
    {
        //Get random position to spawn ball
        Vector3 screenPosition = Camera.main.ScreenToWorldPoint(new Vector3(Random.Range(0, Screen.width), Random.Range(0, Screen.height), Camera.main.farClipPlane / 2));
        GameObject enemie = Instantiate(circleEnemie, screenPosition, Quaternion.identity) as GameObject;
        enemie.name = "enemiecircle";
        enemie.tag = "Enemie";
    }

    // Update is called once per frame
    void Update()
    {
    }

}

And if wanted, here are the enemies inspector specifications Inspector Specifications

Sorry about the link, my reputation points are yet to reach 10 so I can't post images directly.

1
Hi Stellan welcome to Stackoverflow. I've been tasked with reviewing new users posts to help guide them to success. Here's my feedback: My initial thought opening this question up is "No way I'm reading that paragraph of text." I did read it though and I was sad that I had to read so much just to know that you need help with prefabs. I suggest deleting the 2 sentences related to you being new. We can see you're new and don't care to read through that. Ultimately, make your question as short and concise as possible. Show specifically what you're having issues with and then go into detail after.The Muffin Man
People really want to share their knowledge, but they are extremely hesitant to spend much time at all trying to determine if they can help you. Make it very easy for them to determine that quickly. In the mean time I will edit this for you as much as I can.The Muffin Man

1 Answers

0
votes

My guess would be that the Player referenced in your enemy prefab is a prefab itself that never moves.

You should make the prefab field itself of type EnemyController. This makes sure you only can reference a prefab here that actually has an EnemyController attached.

Then after Instantiate you can pass in the player reference of the GameManagement script like

public class GameManagement : MonoBehaviour
{
    // Give this field the correct type
    public EnemyController circleEnemie;

    public Transform player;
    [SerializeField]
    float moveSpeed = 1;
    // Start is called before the first frame update
    void Start()
    {
        //Get random position to spawn ball
        Vector3 screenPosition = Camera.main.ScreenToWorldPoint(new Vector3(Random.Range(0, Screen.width), Random.Range(0, Screen.height), Camera.main.farClipPlane / 2));

        // Instantiate returns the same type as the given prefab
        EnemyController enemy = Instantiate(circleEnemie, screenPosition, Quaternion.identity);
        enemy.name = "enemiecircle";
        enemy.gameObject.tag = "Enemie";

        // Now pass in the player reference
        enemy.player = player;
    }

    // NOTE: When not needed better remove Unity message methods
    // It would just cause overhead
    //void Update()
    //{
    //}
}

Sidenote: In your EnemyController in MoveTowardsPlayer what do you need this for?

Vector3 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

Then whenever dealing with Rigidbody do the things in FixedUpdate otherwise it might break the physics and collision detection!

Then also don't use the Transform values but again the Rigidbody

private void FixedUpdate ()
{
    MoveTowardsPlayer();
}

private void MoveTowardsPlayer ()
{
    var direction = ((Vector2)(player.position - rb.position)). normalized;
    rb.velocity = direction * moveSpeed;
}