Opening door script in C#

Hey there guys , here is the code i’m using. This is launched with a input getkey down and my problem is that when I am near the door and press “F” it just bulges forward a few degrees and then it stops, pressing F again makes it go back to the original position and its this forever, what is the correct way to make the animation of the rotation go through smoothly?

Thanks

{
		var target = Quaternion.Euler (0, doorOpenAngle, 0);
		var target1 = Quaternion.Euler (0, doorCloseAngle, 0);

		Vector3 PlayerPosition = GameObject.Find ("Player").transform.position;
		Vector3 DoorPosition = this.transform.position;
		if(Vector3.Distance(PlayerPosition, DoorPosition) < 5f) {
	
			if(door_Open == false) {
				door_Open = true;
				transform.localRotation = Quaternion.Slerp (transform.localRotation, target, Time.deltaTime * doorAnimSpeed);
		
			}else if(door_Open == true) {
				door_Open = false;
				transform.localRotation = Quaternion.Slerp (transform.localRotation, target1, Time.deltaTime * doorAnimSpeed);

			}
		}
	}

I think, you must change you logic for open door. For example, in your code you press key and first frame you open door on same degree and change status as “open”. In second frame you close door, and change status as “close”, and etc. See simple example below write (write on CSharp):

 public float doorOpenAngle = 90.0f;
 public float doorCloseAngle = 0.0f;
 public float doorAnimSpeed = 2.0f;
 private Quaternion doorOpen = Quaternion.identity;
 private Quaternion doorClose = Quaternion.identity;
 private Transform playerTrans = null;

 public bool doorStatus = false; //false is close, true is open

 private bool doorGo = false; //for Coroutine, when start only one

 void Start() {
  doorStatus = false; //door is open, maybe change
  //Initialization your quaternions
  doorOpen = Quaternion.Euler (0, doorOpenAngle, 0);
  doorClose = Quaternion.Euler (0, doorCloseAngle, 0);
  //Find only one time your player and get him reference
  playerTrans = GameObject.Find ("Player").transform;
 }

 void Update() {
  //If press F key on keyboard
  if (Input.GetKeyDown(KeyCode.F) && !doorGo) {
   //Calculate distance between player and door
   if (Vector3.Distance(playerTrans.position, this.transform.position) < 5f) {
    if (doorStatus) { //close door
     StartCoroutine(this.moveDoor(doorClose));
    } else { //open door
     StartCoroutine(this.moveDoor(doorOpen));
    }
   }
  }
 }

 public IEnumerator moveDoor(Quaternion dest) {
  doorGo = true;
  //Check if close/open, if angle less 4 degree, or use another value more 0
  while (Quaternion.Angle(transform.localRotation, dest) > 4.0f) {
   transform.localRotation = Quaternion.Slerp(transform.localRotation, dest, Time.deltaTime * doorAnimSpeed);
   //UPDATE 1: add yield
   yield return null;
  }
  //Change door status
  doorStatus = !doorStatus;
  doorGo = false;
  //UPDATE 1: add yield
  yield return null;
 }

But maybe, better use Animation Component and create animation for door or use only one angle without quaternions. Desion more. I hope that it will help you.

[Unity 3D] "Openable Door" | Tutorial [UPDATED SCRIPT] - YouTube here is a tutorail video :smiley: hope it helps

Here is my perfect door script:

//Perfect Door/Chest/DrawBridge Animation Script
//Author: HolyFot
//License: CC0
using UnityEngine;
using System.Collections;

public class Door : MonoBehaviour
{
    [SerializeField] public GameObject doorObj;
    [SerializeField] public GameObject pivot;
    [SerializeField] public bool isBackwards = false;
    [SerializeField] private float startY = 0f;
    [SerializeField] public float openSpeed = 100f;
    [SerializeField] public float targetAngle = 90f;
    [SerializeField] public AnimationCurve speedCurve = new AnimationCurve(new Keyframe(0, 0.3f), new Keyframe(0.1f, 0.3f), new Keyframe(0.5f, 1f), new Keyframe(0.9f, 0.3f), new Keyframe(1f, 0.3f));
    [SerializeField] public DoorOpenMethod doorOpenType;

    public bool isOpen = false;
    public bool isTesting = false;
    private bool isOpening = false;
    private bool isClosing = false;
    private Vector3 startPos;

    void Awake()
    {
        if (doorObj == null)
        {
            Debug.LogWarning("Door Object not set!");
            return;
        }
        if (pivot == null)
        {
            Debug.LogWarning("Pivot Object not set!");
            return;
        }

        if (doorOpenType == DoorOpenMethod.X_Mode)
        {
            startY = doorObj.transform.localRotation.eulerAngles.x;
            if (isTesting)
                Debug.Log("start X: " + startY.ToString());
        }
        else if (doorOpenType == DoorOpenMethod.Z_Mode)
        {
            startY = doorObj.transform.localRotation.eulerAngles.z;
            if (isTesting)
                Debug.Log("start Z: " + startY.ToString());
        }
        else if (doorOpenType == DoorOpenMethod.Y_Mode)
        {
            startY = doorObj.transform.localRotation.eulerAngles.y;
            if (isTesting)
                Debug.Log("start Y: " + startY.ToString());
        }
        startPos = doorObj.transform.localPosition;
    }

    void Update()
    {
        if (isTesting)
        {
            if (Input.GetKeyDown(KeyCode.F))
            {
                ToggleDoor();
            }
        }
    }

    public void ToggleDoor()
    {
        if (isOpen)
            CloseDoor();
        else
            OpenDoor();
    }

    public void OpenDoor()
    {
        StopDoorAnims();
        if (!isBackwards)
            StartCoroutine("ForwardDoor2");
        else
            StartCoroutine("ReverseDoor2");
        isOpen = true;
    }

    public void CloseDoor()
    {
        StopDoorAnims();
        if (!isBackwards)
            StartCoroutine("ReverseDoor2");
        else
            StartCoroutine("ForwardDoor2");
        isOpen = false;
    }

    public void StopDoorAnims()
    {
        //if (isOpening)
            StopCoroutine("ForwardDoor2");
        //if (isClosing)
            StopCoroutine("ReverseDoor2");
    }

    private IEnumerator ForwardDoor2()
    {
        if (doorOpenType == DoorOpenMethod.X_Mode)
        {
            while (doorObj.transform.localRotation.eulerAngles.x < startY + targetAngle - 1f)
            {
                float calcSpeed = CalcSpeedRamp2(doorObj.transform.localRotation.eulerAngles.x, startY, startY + targetAngle);
                doorObj.transform.RotateAround(pivot.transform.position, Vector3.right, calcSpeed * Time.deltaTime);
                if (isTesting)
                    Debug.Log("Opening.. X: " + doorObj.transform.localRotation.eulerAngles.x.ToString("0.000"));
                isOpening = true;
                yield return null;
            }
            doorObj.transform.localEulerAngles = new Vector3(targetAngle, doorObj.transform.localEulerAngles.y, doorObj.transform.localEulerAngles.z);
        }
        else if (doorOpenType == DoorOpenMethod.Z_Mode)
        {
            while (doorObj.transform.localRotation.eulerAngles.z < startY + targetAngle - 1f)
            {
                float calcSpeed = CalcSpeedRamp2(doorObj.transform.localRotation.eulerAngles.z, startY, startY + targetAngle);
                doorObj.transform.RotateAround(pivot.transform.position, Vector3.up, calcSpeed * Time.deltaTime);
                if (isTesting)
                    Debug.Log("Opening.. Z: " + doorObj.transform.localRotation.eulerAngles.z.ToString("0.000"));
                isOpening = true;
                yield return null;
            }
            doorObj.transform.localRotation = Quaternion.Euler(doorObj.transform.localRotation.eulerAngles.x, doorObj.transform.localRotation.eulerAngles.y, targetAngle);
        }
        else if (doorOpenType == DoorOpenMethod.Y_Mode) //Rotate around Y
        {
            while (doorObj.transform.localRotation.eulerAngles.y < startY + targetAngle - 1f)
            {
                float calcSpeed = CalcSpeedRamp2(doorObj.transform.localRotation.eulerAngles.y, startY, startY + targetAngle);
                doorObj.transform.RotateAround(pivot.transform.position, Vector3.left, calcSpeed * Time.deltaTime);
                if (isTesting)
                    Debug.Log("Opening.. Y: " + doorObj.transform.localRotation.eulerAngles.y.ToString("0.000"));
                isOpening = true;
                yield return null;
            }
            doorObj.transform.localEulerAngles = new Vector3(doorObj.transform.localEulerAngles.x, targetAngle, doorObj.transform.localEulerAngles.z);
        }
        isOpening = false;
    }

    private IEnumerator ReverseDoor2()
    {
        if (doorOpenType == DoorOpenMethod.X_Mode)
        {
            while (doorObj.transform.localRotation.eulerAngles.x > startY && doorObj.transform.localRotation.eulerAngles.x < targetAngle + 1f)
            {
                float calcSpeed = CalcSpeedRamp2(doorObj.transform.localRotation.eulerAngles.x, startY, startY + targetAngle);
                doorObj.transform.RotateAround(pivot.transform.position, Vector3.right, -1 * calcSpeed * Time.deltaTime);
                if (isTesting)
                    Debug.Log("Close door X: " + doorObj.transform.localRotation.eulerAngles.x.ToString("0.000"));
                isClosing = true;
                yield return null;
            }
            doorObj.transform.localEulerAngles = new Vector3(startY, doorObj.transform.localEulerAngles.y, doorObj.transform.localEulerAngles.z);
            doorObj.transform.localPosition = startPos;
        }
        else if (doorOpenType == DoorOpenMethod.Z_Mode)
        {
            while (doorObj.transform.localRotation.eulerAngles.z > startY && doorObj.transform.localRotation.eulerAngles.z < targetAngle + 1f)
            {
                float calcSpeed = CalcSpeedRamp2(doorObj.transform.localRotation.eulerAngles.z, startY, startY + targetAngle);
                doorObj.transform.RotateAround(pivot.transform.position, Vector3.up, -1 * calcSpeed * Time.deltaTime);
                if (isTesting)
                    Debug.Log("Close door Z: " + doorObj.transform.localRotation.eulerAngles.z.ToString("0.000"));
                isClosing = true;
                yield return null;
            }
            doorObj.transform.localEulerAngles = new Vector3(doorObj.transform.localEulerAngles.x, doorObj.transform.localEulerAngles.y, startY);
            doorObj.transform.localPosition = startPos;
        }
        else if (doorOpenType == DoorOpenMethod.Y_Mode)
        {
            while (doorObj.transform.localRotation.eulerAngles.y > startY && doorObj.transform.localRotation.eulerAngles.y < targetAngle + 1f)
            {
                float calcSpeed = CalcSpeedRamp2(doorObj.transform.localRotation.eulerAngles.y, startY, startY + targetAngle);
                doorObj.transform.RotateAround(pivot.transform.position, Vector3.left, -1 * calcSpeed * Time.deltaTime);
                if (isTesting)
                    Debug.Log("Close door Y: " + doorObj.transform.localRotation.eulerAngles.y.ToString("0.000"));
                isClosing = true;
                yield return null;
            }
            doorObj.transform.eulerAngles = new Vector3(doorObj.transform.rotation.x, startY, doorObj.transform.rotation.z);
            doorObj.transform.localPosition = startPos;
        }
        isClosing = false;
    }

    private float CalcSpeedRamp(float value, float min, float max)
    {
        float curr = 1f;
        float percent = Mathf.Abs(value) / Mathf.Abs(max - min);

        if (percent < 0.3f) //30% speed up
            curr = percent * 10f * openSpeed;
        else if (percent > 0.7f) //70% slow down
            curr = (1f - percent) * 10f * openSpeed; //0.3, 0.2, 0.15, 0.1, 0
        else
            curr = openSpeed; //Regular Speed

        if (curr <= 5f) //1% speed safety
            curr = openSpeed * 0.01f;
        return curr;
    }

    private float CalcSpeedRamp2(float value, float min, float max)
    {
        float curr = 1f;
        float percent = Mathf.Abs(value) / Mathf.Abs(max - min);

        curr = openSpeed * speedCurve.Evaluate(percent);
        return curr;
    }
}

public enum DoorOpenMethod
{
    Z_Mode,
    Y_Mode,
    X_Mode
}