2016-10-07 6 views
0

コライダーがいるときに宇宙船を回したい。しかし、彼らは前方に、箱の衝突者と地形の外に移動し続けます。なぜ宇宙船がボックスコライダーと衝突したのですか?

私は、彼らが衝突したときに引き返すにしたいクローン船を作るスクリプト:それはに行くん

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); 
     } 
    } 
} 

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; 

    /// <summary> 
    ///  How far to place spheres randomly. 
    /// </summary> 
    public Vector3 Extents; 

    /// <summary> 
    ///  How many spheres wanted. 
    /// </summary> 
    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との衝突のスクリプトを2行:

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

しかし、決して元に戻りません。

クローンされた船を作成するスクリプトは、GameObjectの名前球に付けられ、MySphereとしてタグ付けされています。

2番目のスクリプトは、Invisible WallsというGameObjectに添付されています。また、Is Triggerをオンにして(チェックして)ボックスコライダーを追加しました。また、RigidbodyとUse Gravityがチェックされています。

+2

私はそれが正常に機能するシステムの影響を与える、あなたは、彼らがすでに大きなダメージを受けるので – pix

+0

をhttp://gamedev.stackexchange.com/への質問送るべきだと思います。 – Sherlock

+0

'other'変数は宇宙船ですか? – Programmer

答えて

1

LerpメソッドがOnTriggerExitで1回しか呼び出されないためです。 Lerpは通常、時間の経過とともに使用されます。更新またはコルーチンに格納されます。ここでコルーチンでそれを行う方法は次のとおりです。

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; 
    } 
} 
関連する問題