在按下“ 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);
}
}
答案 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导弹在更新中移动