Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有可能在Unity3D中创建更高效的寻的导弹系统?_C#_Unity3d - Fatal编程技术网

C# 是否有可能在Unity3D中创建更高效的寻的导弹系统?

C# 是否有可能在Unity3D中创建更高效的寻的导弹系统?,c#,unity3d,C#,Unity3d,我已经为我的动作平台编写了一个寻的导弹脚本,我忍不住注意到这可能不是最有效的武器 void Start() { target = GameObject.FindGameObjectWithTag("Enemy"); rb = GetComponent<Rigidbody2D>(); } // Update is called once per frame void FixedUpdate() {

我已经为我的动作平台编写了一个寻的导弹脚本,我忍不住注意到这可能不是最有效的武器

void Start()
    {
        target = GameObject.FindGameObjectWithTag("Enemy");
        rb = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        direction = (target.transform.position - transform.position).normalized;
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        rotatetoTarget = Quaternion.AngleAxis(angle, Vector3.forward);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotatetoTarget, Time.deltaTime * rotationSpeed);
        rb.velocity = new Vector2(direction.x * fowrardSpeed, direction.y * fowrardSpeed);
    }
void Start()
{
target=GameObject.FindGameObjectWithTag(“敌人”);
rb=GetComponent();
}
//每帧调用一次更新
void FixedUpdate()
{
方向=(target.transform.position-transform.position)。标准化;
浮动角度=数学Atan2(方向y,方向x)*数学Rad2Deg;
旋转目标=四元数角度轴(角度,矢量3向前);
transform.rotation=Quaternion.Slerp(transform.rotation,rotatetoTarget,Time.deltaTime*rotationSpeed);
rb.velocity=新矢量2(方向.x*fowrardSpeed,方向.y*fowrardSpeed);
}
它工作得很好,但也有一些问题。我如何要求它在每次实例化时随机选择不同的敌人?而不是全力以赴对付一个敌人

同样,一旦敌人死亡,它应该选择一个新的目标,但不会执行
GameObject。在
Update()
中查找()
是件坏事吗?我知道
GameObject.Find()
是要避免的,因为它会遍历场景中的所有游戏对象,直到找到它要查找的对象为止,如果需要,应该只在
Start()
中使用。现在我不得不在武器实例化时使用
GameObject.Find()
,因为我找不到任何其他方法来定位武器的目标。那么,有没有更好的方法来选择一个新的目标,一旦目标被摧毁?我的游戏是一个反应时间很重要的游戏,我不想因为这个武器而造成任何不必要的延迟


谢谢你

你可以有一个
EnemyCache
MisselPawner
脚本

你的
EnemyCache
(很可能是一个单身汉)会有一个世界上的敌人列表
敌人在繁殖时被添加到该列表中,在死亡时从该列表中移除

然后,您的
MissileSpawner
(或生成投射物的东西)脚本需要在每次生成新导弹时为导弹分配一个目标。
它可以通过
EnemyCache
获取新导弹的目标。(您甚至可以筛选列表以获得最近的目标!)

最后,如果旧目标死亡,您的导弹脚本可以从
EnemyCache
中获取新目标

总的来说,它应该类似于:

YourMissile.cs EnemyCache.cs
public class YourMissile : MonoBehaviour {
    // ...

    GameObject target;

    public void Update() {
        // target is destroyed or gone
        if (target == null) {
            SetTargetFromEnemyCache();
        }
    }

    private void SetTargetFromEnemyCache() {
        if (EnemyCache.Instance.TryGetFirstEnemy(out Enemy newTarget)) {
            target = newTarget.gameObject;
        } else {
            Debug.LogWarning("No enemy for missile to target!");
        }
    }

    // ...

    public void SetTarget(GameObject targetToSet) {
        target = targetToSet;
    }

    // ...
}
public class EnemyCache : MonoBehaviour {
    // Singleton
    public static EnemyCache Instance { get; private set; }

    private List<Enemy> cachedEnemies;

    private void Awake() {
        Instance = this;
        cachedEnemies = new List<Enemy>();
        // TODO: Subscribe to a delegate or event, that adds into the 'cachedEnemy' whenever an enemies spawned.
        // Also, an event that removes from 'cachedEnemy' when an enemy dies too.
    }

    // ...

    /// <summary>
    /// Tries to fetch the first enemy in the cache.
    /// </summary>
    /// <param name="enemy">The fetched enemy; Null if there was nothing in cache</param>
    /// <returns>True if there is an enemy fetched; False if none</returns>
    public bool TryGetFirstEnemy(out Enemy enemy) {
        if (cachedEnemies.Count > 0) {
            enemy = cachedEnemies[0];
            return true;
        }
        enemy = null;
        return false;
    }
}
public class YourMissileSpawner : MonoBehaviour {
    [SerializeField]
    private YourMissile missilePrefab;

    // ...

    public void SpawnProjectile() {
        YourMissile newMissile = Instantiate(missilePrefab);

        // Set position... etc...

        // Try to get a target for the new missile
        if (EnemyCache.Instance.TryGetFirstEnemy(out Enemy enemyToTarget)) {
            newMissile.SetTarget(enemyToTarget.gameObject);
        } else {
            Debug.LogWarning("No enemy for newly spawned missile to target!");
        }

        // NOTE: The above is optional,
        // since 'YourMissile' sets a new target from EnemyCache
        // if the target is null; (checks per update)

        // But I included it here in case you want it to filter
        // what kind of enemy it needs to target on start :)
    }
}