如何让宇宙飞船在基地自动着陆?

时间:2017-06-23 10:24:46

标签: c# unity3d unity5

基地是红色立方体。 当游戏开始时,宇宙飞船已经开始移动。 当我点击/按下L按钮时,宇宙飞船旋转到面向基座并开始向它移动,但是当它靠近基座时它会出现意外行为并且宇宙飞船开始围绕基座不间断地滚动。

我想要的是像这个搅拌机的youtube视频一样自动着陆。 我不想要图形,而是它的着陆方式。

Blender landing spaceship

这是一个简短的视频片段,显示我的飞船在开始着陆时:

Landing test

这是我用来控制宇宙飞船的脚本,着陆部分应该是自动的。 该剧本附在宇宙飞船上。

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。还有一个Box Collider。

Base有一个盒子对撞组件。

1 个答案:

答案 0 :(得分:0)

您的车辆上似乎有一个箱式对撞机,当您的代码试图将其带入着陆时,它看起来好像与地形发生碰撞。尝试将对撞机切换为触发器(对撞机组件上的刻度选项)。

然后再试一次,因为这不会造成物理碰撞。如果它因完全不同的原因而起作用或失败,你知道这是原因或促成因素。

编辑:值得注意的是,当试图实现这种效果时,触发动画比尝试在基于物理的代码中实现动画要容易得多。 Unity提供了一些出色的动画控制器,你可以在需要着陆时调用动画,因为你无论如何都要控制玩家。

在执行此操作时,您可以关闭对撞机,这样您就不会发生任何奇怪的碰撞,然后在船需要起飞时将其打开,前提是您需要它。

希望它有所帮助。