为什么在宇宙飞船与箱式对撞机相撞后他们没有回头?

我希望当有一个对撞机时将太空船转回来。 但他们继续前进,开箱即用的对撞机和地形。

使克隆发出的脚本,我想在碰撞时返回:

using System; using UnityEngine; using Random = UnityEngine.Random; using System.Collections; using System.Collections.Generic; public class SphereBuilder : MonoBehaviour { public GameObject SpaceShip; GameObject[] spheres; public float moveSpeed = 50; // for tracking properties change private Vector3 _extents; private int _sphereCount; private float _sphereSize; ///  /// How far to place spheres randomly. ///  public Vector3 Extents; ///  /// How many spheres wanted. ///  public int SphereCount; public float SphereSize; private void Start() { spheres = GameObject.FindGameObjectsWithTag("MySphere"); } private void OnValidate() { // prevent wrong values to be entered Extents = new Vector3(Mathf.Max(0.0f, Extents.x), Mathf.Max(0.0f, Extents.y), Mathf.Max(0.0f, Extents.z)); SphereCount = Mathf.Max(0, SphereCount); SphereSize = Mathf.Max(0.0f, SphereSize); } private void Reset() { Extents = new Vector3(250.0f, 20.0f, 250.0f); SphereCount = 100; SphereSize = 20.0f; } private void Update() { UpdateSpheres(); MoveShips (); //lastPosition = child.position; } private void MoveShips() { foreach (Transform child in spheres[0].transform) { child.transform.position += Vector3.forward * Time.deltaTime * moveSpeed; } } private void UpdateSpheres() { if (Extents == _extents && SphereCount == _sphereCount && Mathf.Approximately(SphereSize, _sphereSize)) return; // cleanup var spheres = GameObject.FindGameObjectsWithTag("Sphere"); foreach (var t in spheres) { if (Application.isEditor) { DestroyImmediate(t); } else { Destroy(t); } } var withTag = GameObject.FindWithTag("Terrain"); if (withTag == null) throw new InvalidOperationException("Terrain not found"); for (var i = 0; i < SphereCount; i++) { var o = Instantiate(SpaceShip); o.tag = "Sphere"; o.transform.SetParent(gameObject.transform); o.transform.localScale = new Vector3(SphereSize, SphereSize, SphereSize); // get random position var x = Random.Range(-Extents.x, Extents.x); var y = Extents.y; // sphere altitude relative to terrain below var z = Random.Range(-Extents.z, Extents.z); // now send a ray down terrain to adjust Y according terrain below var height = 10000.0f; // should be higher than highest terrain altitude var origin = new Vector3(x, height, z); var ray = new Ray(origin, Vector3.down); RaycastHit hit; var maxDistance = 20000.0f; var nameToLayer = LayerMask.NameToLayer("Terrain"); var layerMask = 1 << nameToLayer; if (Physics.Raycast(ray, out hit, maxDistance, layerMask)) { var distance = hit.distance; y = height - distance + y; // adjust } else { Debug.LogWarning("Terrain not hit, using default height !"); } // place ! o.transform.position = new Vector3(x, y, z); } _extents = Extents; _sphereCount = SphereCount; _sphereSize = SphereSize; } } 

和OnTriggerExit函数碰撞的脚本:

 using UnityEngine; using System.Collections; public class InvisibleWalls : MonoBehaviour { public float smooth = 1f; private Vector3 targetAngles; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnTriggerExit(Collider other) { if (other.tag == "Sphere") { targetAngles = other.transform.eulerAngles + 180f * Vector3.up; other.transform.eulerAngles = Vector3.Lerp (other.transform.eulerAngles, targetAngles, smooth * Time.deltaTime); } } } 

它确实达到了两条线:

 targetAngles = other.transform.eulerAngles + 180f * Vector3.up; other.transform.eulerAngles = Vector3.Lerp (other.transform.eulerAngles, targetAngles, smooth * Time.deltaTime); 

但他们永远不会回头。

创建克隆的船只的脚本附加到GameObject名称Spheres并标记为MySphere。

第二个脚本附加到一个名为Invisible Walls的GameObject上,我添加了一个盒子对撞机,Is Trigger设置为on(选中)。 并且还添加了一个Rigidbody和Use Gravity。

这是因为您的Lerp方法仅在OnTriggerExit中调用一次。 Lerp通常用于一段时间,例如Update或coroutine。 以下是如何在协程中执行此操作:

 void OnTriggerExit(Collider other) { if (other.tag == "Sphere") { targetAngles = other.transform.eulerAngles + 180f * Vector3.up; StartCoroutine(TurnShip(other.transform, other.transform.eulerAngles, targetAngles, smooth)) } } IEnumerator TurnShip(Transform ship, Vector3 startAngle, Vector3 endAngle, float smooth) { float lerpSpeed = 0; while(lerpSpeed < 1) { ship.eulerAngles = Vector3.Lerp(startAngle, endAngle, lerpSpeed); lerpSpeed += Time.deltaTime * smooth; yield return null; } }