【问题标题】:Open a Door Front and Back in Unity3D similar to Amnesia在 Unity3D 中打开一扇前后门,类似于失忆症
【发布时间】:2016-05-10 04:15:53
【问题描述】:

我正在尝试实现类似于 Amnesia: The Dark Descent 的功能,它使玩家按住鼠标按钮并在门上向前或向后拖动以打开它(如果您不熟悉,请参阅 Door Example at大约 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);

    }

注意:这个脚本附在有问题的门上。

另外,在确定轮换时,我的代码没有考虑玩家在门的哪一侧。有人对我可以从哪里开始有任何提示吗?

【问题讨论】:

    标签: c# input unity3d rotation quaternions


    【解决方案1】:

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

    1。创建一个简单的 Cube,将其命名为 Door

    2.删除自动附加到新创建的立方体/门的Box Collider

    3。选择,右击并点击“Create Empty”。将该新游戏对象重命名为FrontCollider。确保 FrontCollider 现在是 Door GameObject 的子级。

    4.选择FrontCollider,添加BoxCollider。将碰撞器放置在门的前面(相机的前面)。

    5.复制FrontCollider重命名新游戏对象BackCollider。然后将BackCollider GameObject 移动到Door GameObject 的后面。 确保它正确对齐的最佳方法是如果FrontCollider 的z 位置为-2,则将BackCollider 的z 位置设置为2。所以你要做的就是改变FrontCollider 和@ 的z 位置987654334@ 碰撞器彼此相对。

    5.创建一个空的 GameObject 并将其命名为 Door Parent 确保它不是任何 GameObject 的子级。我们需要使用这个 GameObject 将 Door 的轴心点向左改变。这样门实际上会像门(一侧)一样旋转,而不是围绕自身的中心旋转。

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

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

    当站在门前时,clickholdmove 鼠标向下,它将门打开。向上移动会关闭它。

    当站在门后,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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-03
      • 2018-12-13
      • 1970-01-01
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2017-12-04
      相关资源
      最近更新 更多