将对象移向各自的实例化对象

时间:2019-02-25 11:08:00

标签: c# unity3d

在按下“ A”键时,我试图在远离摄像机的特定区域内生成小行星,并且还生成导弹以击落从摄像机下方生成的精确小行星。理想情况下,您应该能够快速按下此键,并且每次都有新的小行星和导弹预制物生成,然后在碰撞时销毁它们。

问题:当前,每枚导弹都朝着分配有“小行星”标签的第一个物体前进,而不是每枚导弹向其各自的小行星射击。同样,当超快按下时,一些小行星会完全丢失,而导弹被摧毁时,这些小行星不会丢失。 这是我的代码,任何帮助将不胜感激!

分配给导弹预制件:

using System.Collections.Generic;
using UnityEngine;

public class launch : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
    }

    // Update is called once per frame
    public float speed;
    void Update()
    {

        transform.position = Vector3.MoveTowards(transform.position, GameObject.FindGameObjectWithTag("Asteroid").transform.position, speed * Time.deltaTime);
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "Asteroid")
        {
            Destroy(collision.gameObject);
            Destroy(this.gameObject);
        }
    }

}

分配给小行星产生的空白游戏对象

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

public class SpawnAsteroid : MonoBehaviour
{

    public GameObject Asteroidprefab;
    public GameObject Missileprefab;

    public Vector3 center;
    public Vector3 ship;
    public Vector3 size;

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            SpawnSpaceRock();
        }
    }

    public void SpawnSpaceRock()
    {
        Vector3 pos = center + new Vector3(Random.Range(-size.x / 2, size.x / 2), Random.Range(-size.y / 2, size.y / 2), Random.Range(-size.z / 2, size.z / 2));

        Instantiate(Asteroidprefab, pos, Quaternion.identity);
        Instantiate(Missileprefab, ship, Quaternion.identity);
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.color = new Color(1, 0, 0, 0.5f);
        Gizmos.DrawCube(center, size);
    }
}

2 个答案:

答案 0 :(得分:1)

class DeallocPrinter { deinit { print("deallocated") } } struct SomeStruct { let printer = DeallocPrinter() } func makeStruct() { var foo = SomeStruct() } makeStruct() // deallocated becasue it escaped the scope 中使用任何Find方法都是非常糟糕的,因为它很昂贵!

它也仅返回找到的第一个GameObject。


您想要的是在初始化目标引用并使用该引用时将其存储在Update

启动

launch

SpawnAsteroide

public class launch : MonoBehaviour
{
    public GameObject Target;

    public float speed;
void Update()
{
        transform.position = Vector3.MoveTowards(transform.position, Target.transform.position, speed * Time.deltaTime);
    }

    void OnCollisionEnter(Collision collision)
    {
        // Only collide with your specific target
        if (collision.gameObject != Target) return;

        Destroy(Target);
        Destroy(this.gameObject);
    }
}

或者-单个更新

有时候,如果您没有很多对象运行单独的// Hint of you use the correct component type here // you don't even have to use GetComponent later public launch MissilePrefab; public GameObject Asteroideprefab; //... public void SpawnSpaceRock() { Vector3 pos = center + new Vector3(Random.Range(-size.x / 2, size.x / 2), Random.Range(-size.y / 2, size.y / 2), Random.Range(-size.z / 2, size.z / 2)); // store reference of Instantiated GameObject var asteroide = Instantiate(Asteroidprefab, pos, Quaternion.identity); // Store reference of Instantiated launch componemt var missile = Instantiate(Missileprefab, ship, Quaternion.identity); // Now set the taregt missile.Target = asteroid; } 方法,而只有一个集中的Update方法可以控制所有对象,则性能会更好。在这种情况下,您可以使用字典

SpawnAsteroide

Update

而不是全部在中心public float speed; private Dictionary<launch, GameObject> MissileToAsteroid = new Dictionary<launch, GameObject>(); public void SpawnSpaceRock() { Vector3 pos = center + new Vector3(Random.Range(-size.x / 2, size.x / 2), Random.Range(-size.y / 2, size.y / 2), Random.Range(-size.z / 2, size.z / 2)); // store reference of Instantiated GameObject var asteroide = Instantiate(Asteroidprefab, pos, Quaternion.identity); // Store reference of Instantiated launch componemt var missile = Instantiate(Missileprefab, ship, Quaternion.identity); // Since launch is still responsible for different both objects // you still need to pass the reference missile.Target = asteroid; // Add to dictionary MissileToAsteroid [missile] = asteroid; } 方法中运行

Update

然后让void Update() { if (Input.GetKeyDown(KeyCode.A)) { SpawnSpaceRock(); } // TODO: Maybe later remove null elements for better performance // Run each move towards foreach(var kvp in MissileToAsteroid) { var missile = kvp.key; var asteroid = kvp.value; if(missile) { missile.transform.MoveTowards(missile.transform.possition, asteroid.transform.position, speed * Time.deltaTime); } } } 只处理两个对象的销毁(因此在其中删除launch

答案 1 :(得分:0)

在导弹对象中保存目标宝石并使用导弹和宝石列表。数组中的Foreach导弹在更新中移动