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).
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?
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.Create a simple Cube named name it Door.
2.Remove the Box Collider
that is automatically attached to the newly created cube/Door.
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.Select FrontCollider
, add BoxCollider to it. Position the Collider to the front of the Door(Front of camera).
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.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.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.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.
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.
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
}
}