Unity 3D如何设置炮塔自动目标? C#

时间:2015-02-27 17:37:50

标签: c# unity3d

我想要实现的是让我的当前轮换并遵循“敌人”。

此刻它会检测到敌人,但它没有旋转,我不知道为什么。

预制我拖入的子弹,必须有更好的方法来做到这一点?有人有什么建议吗?

目前子弹永远不会触发,但是日志拍摄并且确实......并且旋转不起作用。

这是我的

using UnityEngine;
using System.Collections;

public class TurretController : MonoBehaviour {

    public Rigidbody bulletPrefab;
    private Transform target;
    private GameObject bullet;
    private float nextFire;
    private Quaternion targetPos;

    void OnTriggerEnter(Collider otherCollider) {
        if (otherCollider.CompareTag("Enemy"))
        {
            Debug.Log ("in");
            target = otherCollider.transform;
            StartCoroutine ("Fire");
        }
    }

    void  OnTriggerExit(Collider otherCollider) {
        if (otherCollider.CompareTag("Enemy"))
        {
            Debug.Log ("out");
            target = null;
            StopCoroutine("Fire"); // aborts the currently running Fire() coroutine
        }
    }

    IEnumerator Fire()
    {
        while (target != null)
        {
            nextFire = Time.time + 0.5f;
            while (Time.time < nextFire)
            {
                // smooth the moving of the turret
                targetPos = Quaternion.LookRotation (target.position);
                transform.rotation = Quaternion.Slerp(transform.rotation, targetPos, Time.deltaTime * 5);
                yield return new WaitForEndOfFrame();
            }
            // fire!
            Debug.Log ("shoot");
            bullet = Instantiate(bulletPrefab, transform.position, transform.rotation) as GameObject;
            //bullet.rigidbody.velocity = transform.forward * bulletSpeed;
        }
    }
}

我尝试使用此替换

来更改实例化部分
bullet = (GameObject)Instantiate(bulletPrefab, transform.position, transform.rotation);
            bullet.GetComponent<Bullet>().target = target.transform;

但后来我得到的错误就像“InvalidCastException:无法从源类型转换为目标类型。 TurretController + c__Iterator0.MoveNext()(在Assets / Scripts / TurretController.cs:44)“

2 个答案:

答案 0 :(得分:2)

顺便说一句,这是我在项目中使用的炮塔旋转代码(经许可共享):

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

public class Turret : MonoBehaviour
{
    [SerializeField]
    private float turnRateRadians = 2 * Mathf.PI;

    [SerializeField]
    private Transform turretTop; // the gun part that rotates

    [SerializeField]
    private Transform bulletSpawnPoint;

    private Enemy target;

    void Update()
    {
        TargetEnemy();
    }

    void TargetEnemy()
    {
        if (target == null || target.health <= 0)
            target = Enemy.GetClosestEnemy(turretTop, filter: enemy => enemy.health > 0);

        if (target != null)
        {
            Vector3 targetDir = target.transform.position - transform.position;
            // Rotating in 2D Plane...
            targetDir.y = 0.0f;
            targetDir = targetDir.normalized;

            Vector3 currentDir = turretTop.forward;

            currentDir = Vector3.RotateTowards(currentDir, targetDir, turnRateRadians*Time.deltaTime, 1.0f);

            Quaternion qDir = new Quaternion();
            qDir.SetLookRotation(currentDir, Vector3.up);
            turretTop.rotation = qDir;
        }
    }
}

class Enemy : MonoBehaviour
{
    public float health = 0;

    private static HashSet<Enemy> allEnemies = new HashSet<Enemy>();

    void Awake()
    {
        allEnemies.Add(this);
    }

    void OnDestroy()
    {
        allEnemies.Remove(this);
    }

    /// <summary>
    /// Get the closest enemy to some transform, optionally filtering
    /// (for example, enemies that aren't dead, or enemies of a certain type).
    /// </summary>
    public static Enemy GetClosestEnemy(Transform referenceTransform, System.Predicate<Enemy> filter=null)
    {
        // Left as an exercise for the reader.
        // Remember not to use Vector3.Distance in a loop if you don't need it. ;-)
//      return allEnemies[0];
    }
}

答案 1 :(得分:1)

第一个问题:子弹预制件。变量类型为RigidBody。如果要将其视为游戏对象,则变量必须是游戏对象。或者您可以实例化它,转换为RigidBody,然后使用.gameObject访问器。像这样:

((RigidBody)Instantiate(theRigidbody)).gameObject

第二个问题:用旋转开始简单。如果它不能正常工作,那就不要花哨了。从这样的事情开始(向目标立即旋转):

Vector3 targetDirection = target.transform.position - transform.position;
targetDirection.y = 0; // optional: don't look up
transform.forward = targetDirection;

如果它有效,那么添加一些额外的复杂性,直到它完全符合您的要求。如果你没有把事情搞清楚,请在星期一给我一个喊叫(评论)。我写了炮塔瞄准码(包括最高转速),我不认为我的老板会介意我上传它。