首页 > 解决方案 > 如何使特定的预制件在按下按钮时旋转?

问题描述

我正在设计一个游戏,在我正在设计的当前场景中,大约有 100 个预制件。 在此处输入图像描述

上图显示了对象通常的外观。

我想做的是当我按下红色按钮时,我想让中间的汽车模型旋转。使用 debug.Log 我明白,当我按下 F(use) 时,我希望该特定对象旋转。

到目前为止,我所做的是在代码方面:

        private void SearchForObject()
        {
            if (!m_ItemCoolDown)
            {
                if (m_Target != null)
                {
                    if (m_Target.tag == m_InteractWithObjectsTag)
                    {
                        if (m_WeaponUI != null)
                            m_WeaponUI.ShowPickupMessage("PRESS <color=#FF9200FF>" + m_UseKey + "</color> TO INTERACT WITH THE OBJECT");

                        if (InputManager.GetButtonDown("Use"))
                        {


                            Debug.Log("Button pressed");
                        }
                    }
                }
            }
        }

但是我怎样才能让代码意识到我想要那个对象旋转呢?

大约还有 100 个这样的对象,当我走到他们身边时,按 F,我希望它们也旋转..

我在想是创建一个脚本,并将其附加到按钮,并将汽车模型附加到它,如下所示: 在此处输入图像描述

当我按 F 时,我希望脚本转到另一个脚本,抓取特定模型然后旋转。但我不知道该怎么做,有人知道吗?

谢谢

标签: unity3d

解决方案


我假设你的脚本基本上做了它应该做的。

我会采用您已经提到的内容,让按钮本身存储对其目标对象的引用并处理旋转。

对于旋转,您可以使用简单的Coroutine

public class ButtonScript : MonoBehaviour
{
    // The object that should rotate
    public Transform ObjectToTransform;

    // How long it should take to rotate in seconds
    public float RotationDuration = 1;

    // flag for making sure you can start rotating only if not already rotating
    private bool _isRotating;

    public void StartRotating()
    {
        // if already rotating do nothing
        if(_isRotating) return;

        StartCoroutine(Rotate());
    }

    // Rotates the ObjectToTransform 360° around its world up vector
    // in RotationDuration seconds
    private IEnumerator Rotate()
    {
        // set the flag so rotation can not be started multiple times
        _isRotating= true;

        // store the original rotation the target object currently has
        var initialRotation = ObjectToTransform.rotation;

        // we can already calculate the rotation speed in angles / second
        var rotationspeed = 360 / RotationDuration;

        // Rotate the object until the given duration is reached
        var timePassed = 0;    
        while(timePassed < RotationDuration)
        {
            // Time.deltaTime gives you the time passed since the last frame in seconds 
            // So every frame turn the object around world Y axis a little
            ObjectToTransform.Rotate(0, rotationspeed  * Time.deltaTime, 0, Space.World);

            // add the time passed since the last frame to the timePassed            
            timePassed += Time.deltaTime;

            // yield makes the Courutine interupt here so the frame can be rendered 
            // but the it "remembers" at which point it left
            // so in the next frame it goes on executing the code from the next line
            yield return null;
        }

        // Just to be sure we end with a clean rotation reset to the initial rotation in the end
        // since +360°  
        ObjectToTransform.rotation = initialRotation;

        // reset the flag so rotation can be started again
        _isRotating= false;
    }
}

所以我还假设这m_Target是您要按下的特定“按钮”,而不是现在剩下的就是在该按钮上启动协程:

private void SearchForObject()
{
    if (!m_ItemCoolDown)
    {
        if (m_Target != null)
        {
            if (m_Target.tag == m_InteractWithObjectsTag)
            {
                if (m_WeaponUI != null)
                    m_WeaponUI.ShowPickupMessage("PRESS <color=#FF9200FF>" + m_UseKey + "</color> TO INTERACT WITH THE OBJECT");

                if (InputManager.GetButtonDown("Use"))
                {
                    Debug.Log("Button pressed");

                    // if m_Target is not the button you'll have to get a reference
                    // to the button somehow
                    m_Target.GetComponent<ButtonScript>.StartRotating();
                }
            }
        }
    }
}

并将检查器中的引用设置为targetObject应该旋转的对象。或者,如果它是一个被初始化的预制件,你可以做类似的事情

var obj = Initialize(prefab /*, parameters if you have some*/);
// ButtonObject is the reference to your button GameObject
ButtonObject.GetComponent<ButtonScript>().targetObject = obj.transform;

推荐阅读