与失忆症类似,在Unity3D中打开门的前部和后部 [英] Open a Door Front and Back in Unity3D similar to Amnesia

查看:100
本文介绍了与失忆症类似,在Unity3D中打开门的前部和后部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to implement a feature similar to Amnesia: The Dark Descent's that makes the player hold down the mouse button and drag forwards or backwards on a door in order to open it (if you are not familiar see Door Example at about 36:30).

我有以下代码,并且可以正常工作,但是开口有点抖动并且前后来回跳动,而且我无法弄清楚是否使用了transform.Rotate错误:

I have the following code, and it sort of works, but the opening is jittery and bounces back and forth a bit, and I cannot figure out if I'm using transform.Rotate incorrectly:

    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);

    }

注意:此脚本已附加到相关门上.

Note: this script is attached to the door in question.

此外,在确定旋转角度时,我的代码没有考虑玩家在门的哪一侧.有人对我从哪里开始有任何提示吗?

Also, my code doesn't take into account which side of the door the player is on when it comes to determining rotation. Does anyone have any tips on where I might start with that?

推荐答案

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

The code in your question is too small to accomplish that. Any ways you can easily do that by changing the transform.localEulerAngles. The code I attached in this answer can do that. T test the the script, follow direction below. This also describe how to determine front and back doors.

1 .创建一个名为 Door 的简单多维数据集.

1.Create a simple Cube named name it Door.

2 .删除自动附加到新创建的多维数据集/门的Box Collider.

2.Remove the Box Collider that is automatically attached to the newly created cube/Door.

3 .选择,右键单击并单击"创建空".将该新的GameObject重命名为FrontCollider.确保FrontCollider现在是Door GameObject 的子级.

3. Select the Door, Right click on and click "Create Empty". Rename that new GameObject to FrontCollider. Make sure that FrontCollider is now the child of Door GameObject.

4 .选择FrontCollider,然后将BoxCollider添加到其中.将对撞机放在门的前面(摄像机的前面).

4.Select FrontCollider, add BoxCollider to it. Position the Collider to the front of the Door(Front of camera).

5 .复制FrontCollider重命名新的GameObject BackCollider.然后将BackCollider GameObject移到 Door GameObject的背面. 确保FrontCollider的z位置为-2的最佳方法是将BackCollider的z位置设置为2.因此,您要做的就是更改FrontColliderBackCollider对撞机彼此相对.

5.Duplicate FrontCollider and rename the new GameObject BackCollider. Then move the BackCollider GameObject to the back of the Door GameObject. The best way to make sure that it aligns well is if the z position of the FrontCollider is -2, set the z position of BackCollider to 2. So all you do is change the z position of FrontCollider and BackCollider colliders to be opposite of each other.

5 .创建一个空的GameObject并将其命名为 Door Parent (确保父门),确保它不是任何GameObject的子代.我们需要使用此GameObject将门"的枢轴点更改为左侧.这样一来,门实际上就会像一扇门(一侧)一样旋转,而不是围绕其中心旋转.

5.Create an empty GameObject and name it Door Parent Make sure it is not a child of any GameObject. We need to use this GameObject to change the pivot point of the Door to the left. So that the Door will actually rotate like a door (one side)instead of around the center of itself.

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

6.Use the Move Tool and Move the Door Parent Gameobject to the left side of the Door. Do NOT rotate it. Just move it. Once you think that wherever the Door Parent is now located is where the Door should rotate around, attach the Door Script below to the Door Parent GameObject not the Door GameObject.

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

7.Drag the FrontCollider GameObject to the frontDoorCollider slot in the script. Drag the BackCollider GameObject to the backDoorColliderin slot in the script. That's it.

当站在门前时,将鼠标按下clickholdmove,它将拉动打开门.向上移动将其关闭.

When standing in front of the door, click, hold and move the mouse down, it will PULL the door open. Moving it up will close it.

当停在门后时,将鼠标悬停在clickholdmove上,它将推入门打开.向上移动将其关闭.

When stading in the back of the door, click, hold and move the mouse up, it will PUSH the door open. Moving it up will close it.

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
    }
}

这篇关于与失忆症类似,在Unity3D中打开门的前部和后部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆