我怎样才能让飞船自动降落在基地上?
How can i make the spaceship to land automatic on the base?
底座是一个红色立方体。
游戏开始时飞船已经在移动了。
当我 click/press L 按钮时,飞船旋转面向基地并开始向它移动,但是当它接近基地时,它的行为出乎意料,飞船开始不停地绕着基地滚动。
我想要的是像这个 blender 的 youtube 视频一样自动登陆。
我不想要图形,只想要它着陆的方式。
这是一个简短的视频剪辑,展示了我的飞船开始着陆时的样子:
这是我用来控制宇宙飞船的脚本,着陆部分应该是自动的。
脚本附在飞船上
using UnityEngine;
using System.Collections;
public class ControlShip : MonoBehaviour {
public int rotationSpeed = 75;
public int movementspeed = 10;
public int thrust = 10;
public float RotationSpeed = 5;
private bool isPKeyDown = false;
private float acceleration = .0f;
private Vector3 previousPosition = Vector3.zero;
private Rigidbody _rigidbody;
private bool landing = false;
private Vector3 originPosition;
private Vector3 lastPosition;
private const float minDistance = 0.2f;
private Transform baseTarget;
// Use this for initialization
void Start () {
baseTarget = GameObject.Find("Base").transform;
originPosition = transform.position;
_rigidbody = GetComponent<Rigidbody>();
Debug.Log("Acc Speed: " + thrust);
}
// Update is called once per frame
void Update()
{
if (landing == false)
{
var v3 = new Vector3(Input.GetAxis("Vertical"), Input.GetAxis("Horizontal"), 0.0f);
transform.Rotate(v3 * rotationSpeed * Time.deltaTime);
transform.position += transform.forward * Time.deltaTime * movementspeed;
if (Input.GetKey(KeyCode.Z))
transform.Rotate(Vector3.forward * rotationSpeed * Time.deltaTime);
if (Input.GetKey(KeyCode.R))
transform.Rotate(Vector3.right * rotationSpeed * Time.deltaTime);
if (Input.GetKey(KeyCode.P))
{
isPKeyDown = Input.GetKey(KeyCode.P);
float distance = Vector3.Distance(previousPosition, transform.position);
acceleration = distance / Mathf.Pow(Time.deltaTime, 2);
previousPosition = transform.position;
_rigidbody.AddRelativeForce(0f, 0f, thrust, ForceMode.Acceleration);
}
}
else
{
transform.position += transform.forward * Time.deltaTime * movementspeed;
var targetRotation = Quaternion.LookRotation(baseTarget.position - transform.position);
var str = Mathf.Min(.5f * Time.deltaTime, 1);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, str);
}
if (landed == true)
TakeOff();
if (Input.GetKey(KeyCode.L))
{
landing = true;
lastPosition = transform.position;
}
}
void OnTriggerEnter(Collider other)
{
if (landing == true && other.gameObject.name == "Base")
{
StartCoroutine(Landed());
}
}
bool landed = false;
IEnumerator Landed()
{
yield return new WaitForSeconds(5);
Debug.Log("Landed");
landed = true;
}
private void TakeOff()
{
if (transform.position != originPosition)
{
_rigidbody.AddForce(transform.up * 10);
}
if ((transform.position - originPosition).sqrMagnitude <= (1f * 1f))
{
landed = false;
_rigidbody.useGravity = false;
}
}
void OnGUI()
{
if (isPKeyDown)
{
GUI.Label(new Rect(100, 100, 200, 200), "Acc Speed: " + acceleration);
}
}
}
这是登陆的部分,应该是登陆的部分:
transform.position += transform.forward * Time.deltaTime * movementspeed;
var targetRotation = Quaternion.LookRotation(baseTarget.position - transform.position);
var str = Mathf.Min(.5f * Time.deltaTime, 1);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, str);
宇宙飞船有两个组件:Rigidbody,Use Gravity 设置为 true。还有一个盒子对撞机。
基地有一个盒子碰撞器组件。
您的车辆上似乎有一个盒子对撞机,当您的代码试图将其带入着陆时,它看起来好像正在与地形发生碰撞。尝试将对撞机切换为触发器(对撞机组件上的勾选选项)。
然后再试一次,这样不会造成物理碰撞。如果它由于完全不同的原因而工作或失败,你知道这是原因或促成因素。
编辑:还值得注意的是,在尝试实现这种效果时,触发动画比尝试在基于物理的代码中实现动画要容易得多。 Unity 提供了一些很棒的动画控制器,您可以在需要着陆时调用动画,因为无论如何您都会从玩家手中夺走控制权。
在执行此操作时,您可以关闭对撞机,这样您就不会发生任何奇怪的碰撞,然后在船需要起飞时打开它,当然前提是您需要它。
希望对您有所帮助。
底座是一个红色立方体。 游戏开始时飞船已经在移动了。 当我 click/press L 按钮时,飞船旋转面向基地并开始向它移动,但是当它接近基地时,它的行为出乎意料,飞船开始不停地绕着基地滚动。
我想要的是像这个 blender 的 youtube 视频一样自动登陆。 我不想要图形,只想要它着陆的方式。
这是一个简短的视频剪辑,展示了我的飞船开始着陆时的样子:
这是我用来控制宇宙飞船的脚本,着陆部分应该是自动的。 脚本附在飞船上
using UnityEngine;
using System.Collections;
public class ControlShip : MonoBehaviour {
public int rotationSpeed = 75;
public int movementspeed = 10;
public int thrust = 10;
public float RotationSpeed = 5;
private bool isPKeyDown = false;
private float acceleration = .0f;
private Vector3 previousPosition = Vector3.zero;
private Rigidbody _rigidbody;
private bool landing = false;
private Vector3 originPosition;
private Vector3 lastPosition;
private const float minDistance = 0.2f;
private Transform baseTarget;
// Use this for initialization
void Start () {
baseTarget = GameObject.Find("Base").transform;
originPosition = transform.position;
_rigidbody = GetComponent<Rigidbody>();
Debug.Log("Acc Speed: " + thrust);
}
// Update is called once per frame
void Update()
{
if (landing == false)
{
var v3 = new Vector3(Input.GetAxis("Vertical"), Input.GetAxis("Horizontal"), 0.0f);
transform.Rotate(v3 * rotationSpeed * Time.deltaTime);
transform.position += transform.forward * Time.deltaTime * movementspeed;
if (Input.GetKey(KeyCode.Z))
transform.Rotate(Vector3.forward * rotationSpeed * Time.deltaTime);
if (Input.GetKey(KeyCode.R))
transform.Rotate(Vector3.right * rotationSpeed * Time.deltaTime);
if (Input.GetKey(KeyCode.P))
{
isPKeyDown = Input.GetKey(KeyCode.P);
float distance = Vector3.Distance(previousPosition, transform.position);
acceleration = distance / Mathf.Pow(Time.deltaTime, 2);
previousPosition = transform.position;
_rigidbody.AddRelativeForce(0f, 0f, thrust, ForceMode.Acceleration);
}
}
else
{
transform.position += transform.forward * Time.deltaTime * movementspeed;
var targetRotation = Quaternion.LookRotation(baseTarget.position - transform.position);
var str = Mathf.Min(.5f * Time.deltaTime, 1);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, str);
}
if (landed == true)
TakeOff();
if (Input.GetKey(KeyCode.L))
{
landing = true;
lastPosition = transform.position;
}
}
void OnTriggerEnter(Collider other)
{
if (landing == true && other.gameObject.name == "Base")
{
StartCoroutine(Landed());
}
}
bool landed = false;
IEnumerator Landed()
{
yield return new WaitForSeconds(5);
Debug.Log("Landed");
landed = true;
}
private void TakeOff()
{
if (transform.position != originPosition)
{
_rigidbody.AddForce(transform.up * 10);
}
if ((transform.position - originPosition).sqrMagnitude <= (1f * 1f))
{
landed = false;
_rigidbody.useGravity = false;
}
}
void OnGUI()
{
if (isPKeyDown)
{
GUI.Label(new Rect(100, 100, 200, 200), "Acc Speed: " + acceleration);
}
}
}
这是登陆的部分,应该是登陆的部分:
transform.position += transform.forward * Time.deltaTime * movementspeed;
var targetRotation = Quaternion.LookRotation(baseTarget.position - transform.position);
var str = Mathf.Min(.5f * Time.deltaTime, 1);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, str);
宇宙飞船有两个组件:Rigidbody,Use Gravity 设置为 true。还有一个盒子对撞机。
基地有一个盒子碰撞器组件。
您的车辆上似乎有一个盒子对撞机,当您的代码试图将其带入着陆时,它看起来好像正在与地形发生碰撞。尝试将对撞机切换为触发器(对撞机组件上的勾选选项)。
然后再试一次,这样不会造成物理碰撞。如果它由于完全不同的原因而工作或失败,你知道这是原因或促成因素。
编辑:还值得注意的是,在尝试实现这种效果时,触发动画比尝试在基于物理的代码中实现动画要容易得多。 Unity 提供了一些很棒的动画控制器,您可以在需要着陆时调用动画,因为无论如何您都会从玩家手中夺走控制权。
在执行此操作时,您可以关闭对撞机,这样您就不会发生任何奇怪的碰撞,然后在船需要起飞时打开它,当然前提是您需要它。
希望对您有所帮助。