为什么在宇宙飞船与盒对撞机相撞后它们不回头? [英] Why after the spaceships collide with the box collider they are not turning back?
问题描述
我希望当有对撞机时,将飞船转回原处.但是它们一直在前进,并脱离了对撞机和地形.
I want that when there is a collider turn the spaceship/s back. But they keep moving forward and out of the box collider and terrain.
构成克隆的脚本会在它们发生碰撞时向后退回:
The script that make the clones ships that i want to turn back when they collide:
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冲突的脚本:
And the script of the colliding with the function 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.
The script that create the cloned ships is attached to a GameObject name Spheres and tagged as MySphere.
第二个脚本附加到一个名为Invisible Walls的GameObject上,我在其中添加了一个框碰撞器,将Is Trigger设置为on(选中).并添加了一个刚体并选中了使用重力".
The second script is attached to a GameObject called Invisible Walls and that i added to it a box collider with the Is Trigger set to on(checked). And also added to it a Rigidbody and Use Gravity is checked on.
推荐答案
这是因为您的Lerp方法在OnTriggerExit中仅被调用一次.通常会随着时间的推移使用Lerp,例如在Update或协程中.这是在协程中执行此操作的方法:
It's because your Lerp method is only called once in OnTriggerExit. Lerp is usually used over time e.g. in Update or a coroutine. Here's how to do it in a 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;
}
}
这篇关于为什么在宇宙飞船与盒对撞机相撞后它们不回头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!