【问题标题】:Rotating a gameobject to a specific point [duplicate]将游戏对象旋转到特定点[重复]
【发布时间】:2017-01-14 15:05:52
【问题描述】:

在我的项目中,当我与桥发生碰撞时,我有一座桥,它旋转并且不停止旋转,我想要的是通过特定点旋转该桥并停止旋转,该桥位于游戏对象内这是我的枢轴点,一般我旋转枢轴点而不是桥,所以我这样做了:

using UnityEngine;
using System.Collections;

public class fallBridge : MonoBehaviour {

    private Rigidbody ball;
    public GameObject bridgePivot;
    private bool colided; 
    private bool rotating = true;
    // Update is called once per frame

    void Start(){
        colided = false;
    }

    void Update () {
        if (colided) {
            if (rotating) {
                Vector3 to = new Vector3 (0, 0, -85);
                if (Vector3.Distance (bridgePivot.transform.eulerAngles, to) > 0.01f) {
                    bridgePivot.transform.eulerAngles = Vector3.Lerp (bridgePivot.transform.rotation.eulerAngles, to, Time.deltaTime);
                } else {
                    bridgePivot.transform.eulerAngles = to;
                    rotating = false;
                }
            }
        }
    }

    void OnCollisionEnter(Collision other)
    {
        ball = GameObject.FindWithTag ("Player").GetComponent<Rigidbody> ();
        if (other.gameObject.tag == "Player" && ball.transform.localScale == new Vector3(2.0f,2.0f,2.0f)) {
            Debug.Log("ENTER");
            colided = true;
        }
    }
}

我做错了什么??碰撞检测工作完美,但在更新方法上它永远不会停止旋转:S

【问题讨论】:

  • debug.log 看看为什么不满足条件if (Vector3.Distance (bridgePivot.transform.eulerAngles, to) &gt; 0.01f)

标签: c# unity3d rotation unity5


【解决方案1】:

应该用协程来做这件事。在调用OnCollisionEnter 时,调用协程函数并传入要旋转的GameOjbect 和要旋转到的角度。您可以阅读此功能的工作原理here

下面的示例将在 3 秒内沿 z 轴旋转 GameObject -85 度数。 您可以将其更改为适合您的任何内容。

public class fallBridge : MonoBehaviour
{
    private Rigidbody ball;
    public GameObject bridgePivot;
    bool rotating = false;

    void OnCollisionEnter(Collision other)
    {
        ball = GameObject.FindWithTag("Player").GetComponent<Rigidbody>();
        if (other.gameObject.CompareTag("Player") && ball.transform.localScale == new Vector3(2.0f, 2.0f, 2.0f))
        {
            Debug.Log("ENTER");
            Vector3 rotationAngle = new Vector3(0, 0, -85);
            StartCoroutine(RotateObject(bridgePivot, rotationAngle, 3f));
        }
    }

IEnumerator RotateObject(GameObject gameObjectToMove, Vector3 eulerAngles, float duration)
{
    if (rotating)
    {
        yield break;
    }
    rotating = true;

    Vector3 newRot = gameObjectToMove.transform.eulerAngles + eulerAngles;

    Vector3 currentRot = gameObjectToMove.transform.eulerAngles;

    float counter = 0;
    while (counter < duration)
    {
        counter += Time.deltaTime;
        gameObjectToMove.transform.eulerAngles = Vector3.Lerp(currentRot, newRot, counter / duration);
        yield return null;
    }
    rotating = false;
}

【讨论】:

    【解决方案2】:

    错误在这一行:

    bridgePivot.transform.eulerAngles = Vector3.Lerp (bridgePivot.transform.rotation.eulerAngles, to, Time.deltaTime);
    

    当您使用 Lerp 时,您通常有一个固定的开始和结束,并且您使最后一个参数 (t) 从 0 变为 1。在您的情况下,端点是固定的,t 参数也是固定的,您可以改变开始.这意味着您每次更新都会朝着目标迈出一小步,但这一步只是百分比。所以每次更新你都会更近一步,你的下一步会更小。

    你应该做的是记住你开始的时候在哪里,什么时候开始的。您还需要为您的网桥定义一个速度。然后,您可以将桥从头移动到尾并控制速度。

    public class fallBridge : MonoBehaviour {
    
        private Rigidbody ball;
        public GameObject bridgePivot;
        public float rotateDuration = 2; // Time in seconds
        // When you begin rotating you fill these three variables
        private float startTime;
        private Vector3 from;
        private bool rotating = false;
        // If the target doesn't change you might as well define it beforehand
        private Vector3 to = new Vector3 (0, 0, -85);
    
        void Update () {
            if (rotating) {
                float t = (Time.time - startTime) / rotateDuration;
                if (t < 1) {
                    bridgePivot.transform.eulerAngles = Vector3.Lerp (from, to, t);
                } else {
                    bridgePivot.transform.eulerAngles = to;
                    rotating = false;
                }
            }
        }
    
        void OnCollisionEnter(Collision other)
        {
            ball = GameObject.FindWithTag ("Player").GetComponent<Rigidbody> ();
            if (other.gameObject.tag == "Player" && ball.transform.localScale == new Vector3(2.0f,2.0f,2.0f)) {
                Debug.Log("ENTER");
                startTime = Time.time; // Begin now
                from = bridgePivot.transform.eulerAngles; // Remember the start position
                rotating = true; // Signal to start rotating
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-26
      • 2018-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多