在 Unity3D 中打开一扇前后门,类似于 Amnesia

Open a Door Front and Back in Unity3D similar to Amnesia

我正在尝试实现类似于失忆症的功能:黑暗后裔让玩家按住鼠标按钮并在门上向前或向后拖动以打开它(如果您不熟悉,请参阅 Door Example 大约 36:30).

我有下面的代码,它有点用,但是开头有点抖动,有点来回跳动,我不知道我是否在使用 transform.Rotate 不正确:

    if (previousMousePosition == garbageVector) // if this is the first frame, create a reference for previousMousePosition
        previousMousePosition = Input.mousePosition;
    else
    {
        // else find the difference and rotate
        rotationAmount = (Input.mousePosition.x - previousMousePosition.x);
        if (rotationAmount < 0)
            this.transform.Rotate(Vector3.up * rotationSpeed * Time.deltaTime);
        else if (rotationAmount > 0)
            this.transform.Rotate(Vector3.down * rotationSpeed * Time.deltaTime);

    }

注意:此脚本附在相关门上。

此外,我的代码在确定旋转时没有考虑玩家在门的哪一侧。有人对我可以从哪里开始有任何建议吗?

您问题中的代码太小,无法完成。您可以通过更改 transform.localEulerAngles 轻松实现的任何方式。我在这个答案中附加的代码可以做到这一点。 T 测试脚本,按照下面的说明进行操作。这也描述了如何确定前门和后门。

1。创建一个简单的立方体,命名为 Door

2.删除自动附加到新创建的cube/Door.

Box Collider

3。 Select ,右键单击并单击“创建空”。将该新游戏对象重命名为 FrontCollider。确保 FrontCollider 现在是 Door GameObject 的子对象。

4.Select FrontCollider,给它加上BoxCollider。将 Collider 定位到门的前面(相机前面)。

5。复制 FrontCollider重命名 新游戏对象 BackCollider。然后将 BackCollider GameObject 移动到 Door GameObject 的后面。 确保对齐良好的最佳方法是,如果 FrontCollider 的 z 位置为 -2,则将 BackCollider 的 z 位置设置为 2。因此,您要做的就是更改 [的 z 位置=13=] 和 BackCollider 对撞机彼此相对。

5。创建一个空的 GameObject 并将其命名为 Door Parent 确保它不是任何 GameObject 的子对象。我们需要使用此游戏对象将门的轴心点更改为左侧。这样门实际上会像门一样旋转(一侧),而不是绕着它自己的中心旋转。

6。使用移动工具并将 Door Parent 游戏对象移动到门的左侧。不要旋转它。移动它。一旦您认为 Door Parent 现在所在的位置就是 Door 应该旋转的位置,请将下面的 Door Script 附加到 Door Parent 游戏对象不是 Door 游戏对象。

7。将 FrontCollider GameObject 拖到脚本中的 frontDoorCollider 插槽中。 将 BackCollider GameObject 拖到脚本中的 backDoorColliderin 插槽中。就是这样。

站在门前,clickholdmove鼠标按下,会PULL开门.向上移动它会关闭它。

站在门后面时,clickholdmove鼠标向上,会门打开。向上移动它会关闭它。

public class Door : MonoBehaviour
{
    public float ySensitivity = 300f;
    public float frontOpenPosLimit = 45;
    public float backOpenPosLimit = 45;

    public GameObject frontDoorCollider;
    public GameObject backDoorCollider;

    bool moveDoor = false;
    DoorCollision doorCollision = DoorCollision.NONE;


    // Use this for initialization
    void Start()
    {
        StartCoroutine(doorMover());
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("Mouse down");

            RaycastHit hitInfo = new RaycastHit();
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo))
            {
                if (hitInfo.collider.gameObject == frontDoorCollider)
                {
                    moveDoor = true;
                    Debug.Log("Front door hit");
                    doorCollision = DoorCollision.FRONT;
                }
                else if (hitInfo.collider.gameObject == backDoorCollider)
                {
                    moveDoor = true;
                    Debug.Log("Back door hit");
                    doorCollision = DoorCollision.BACK;
                }
                else
                {
                    doorCollision = DoorCollision.NONE;
                }
            }
        }

        if (Input.GetMouseButtonUp(0))
        {
            moveDoor = false;
            Debug.Log("Mouse up");
        }
    }

    IEnumerator doorMover()
    {
        bool stoppedBefore = false;
        float yRot = 0;

        while (true)
        {
            if (moveDoor)
            {
                stoppedBefore = false;
                Debug.Log("Moving Door");

                yRot += Input.GetAxis("Mouse Y") * ySensitivity * Time.deltaTime;


                //Check if this is front door or back
                if (doorCollision == DoorCollision.FRONT)
                {
                    Debug.Log("Pull Down(PULL TOWARDS)");
                    yRot = Mathf.Clamp(yRot, -frontOpenPosLimit, 0);
                    Debug.Log(yRot);
                    transform.localEulerAngles = new Vector3(0, -yRot, 0);
                }
                else if (doorCollision == DoorCollision.BACK)
                {
                    Debug.Log("Pull Up(PUSH AWAY)");
                    yRot = Mathf.Clamp(yRot, 0, backOpenPosLimit);
                    Debug.Log(yRot);
                    transform.localEulerAngles = new Vector3(0, yRot, 0);
                }
            }
            else
            {
                if (!stoppedBefore)
                {
                    stoppedBefore = true;
                    Debug.Log("Stopped Moving Door");
                }
            }

            yield return null;
        }

    }


    enum DoorCollision
    {
        NONE, FRONT, BACK
    }
}