首页 > 解决方案 > 实例化的预制件没有按预期移动

问题描述

我在 Unity 中实例化预制件时遇到问题。

我正在开发一个游戏,你的敌人向你移动,你必须杀死他们。我最初的敌人游戏对象几乎没有问题地向玩家移动,但该对象的实例不会移动。

更令人困惑的是,当我复制游戏对象并将其添加到场景中而不实例化时,两个游戏对象都会向玩家移动就好了。

敌人脚本:

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));

    }
}

实例化代码

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()
    {
    }

}

如果需要,这里是敌人检查员的规格 检查员规范

抱歉链接,我的声望点还没有达到 10,所以我不能直接发布图片。

标签: c#unity3d

解决方案


我的猜测是Player你的敌人预制件中引用的预制件本身就是一个永远不会移动的预制件。

您应该将预制字段本身设为 type EnemyController。这确保您只能在此处引用实际附加的预制EnemyController

然后在实例化之后,您可以传入GameManagement脚本的播放器引用,例如

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()
    //{
    //}
}

旁注:你需要这个做什么EnemyControllerMoveTowardsPlayer

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

然后无论何时处理,Rigidbody否则FixedUpdate它可能会破坏物理和碰撞检测!

然后也不要使用这些Transform值,而是再次使用刚体

private void FixedUpdate ()
{
    MoveTowardsPlayer();
}

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

推荐阅读