Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by Gascon · Feb 08, 2015 at 05:46 PM · c#quaterniondoorslerpproximity

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);
 
             }
         }
     }    
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image blaxCZ · Jan 08, 2017 at 03:24 PM 0
Share

Hi, the fault is in logic - when the door is closed, you rightfully say to open it, but immediately in the next frame you say, in the else if part, to close it :-) I just figured one way to do this: Opening with a button object (assign the doors to object "door"):

 using UnityEngine;
 using System.Collections;
 using UnityEngine.UI;
 
 
 public class OpenDoor : $$anonymous$$onoBehaviour
 {
     // Smothly open a door
     float smooth = 2.0f;
     float DoorOpenAngle = 90.0f;
     private bool open = false;
 
     private Vector3 defaultRot;
     private Vector3 openRot;
 
     public Transform door;
 
     void Start()
     {
         defaultRot = door.eulerAngles;
         openRot = new Vector3(defaultRot.x, defaultRot.y + DoorOpenAngle, defaultRot.z);
     }
 
     void On$$anonymous$$ouseDown()
     {
         open = !open;
     }
 
     void Update()
     {
         Debug.Log(open);
         if (open)
         {
             //Open door
             door.eulerAngles = Vector3.Slerp(door.eulerAngles, openRot, Time.deltaTime * smooth);
         }
         else
         {
             //Close door
             door.eulerAngles = Vector3.Slerp(door.eulerAngles, defaultRot, Time.deltaTime * smooth);
 
         }
     }
 }

3 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by zharik86 · Feb 08, 2015 at 07:22 PM

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.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Gascon · Feb 08, 2015 at 07:54 PM 0
Share

A clean script with your code returns me this , now im not really used to quaternions in general so i have really no idea how to use them properly... I would have guessed it would be easy just to rotate the Y but i would guess not , have any idea how to fix that?

Assets/Scripts/door.cs(40,28): error CS0161: `door.moveDoor(UnityEngine.Quaternion)': not all code paths return a value

avatar image zharik86 · Feb 09, 2015 at 07:20 AM 0
Share

@Gascon Oh, sorry, in Coroutine must add yield return. I update my answer. If you want create rotate door, sing only one y-angle and you need help, just write me.

avatar image Gascon · Feb 11, 2015 at 10:32 PM 0
Share

Pretty neat works like a charm, now thats its working i feel more at ease to tweak it to my likings , Thanks!

avatar image PandoWooSetti · Jun 20, 2015 at 10:00 PM 0
Share

Hey, i am also trying to get a decent door script. I tried your example @zharik86. But when i play it says

"NullReferenceException: Object reference not set to an instance of an object OpenDoorBasic.Update () (at Assets/OpenDoorBasic.cs:30)"

So what am i doing wrong? It's attacked to the Hinge of the main door.

avatar image Faetal32 · Jul 02, 2015 at 02:30 AM 0
Share

@PandoWooSetti rename your first person controller or third person controller GameObject to "Player". This should fix your problem.

Show more comments
avatar image
0

Answer by Johnz1234 · Feb 08, 2015 at 07:37 PM

https://www.youtube.com/watch?v=vfL7kQeZtic here is a tutorail video :D hope it helps

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Gascon · Feb 08, 2015 at 10:54 PM 0
Share

that's javascript... useless in my case ! Sorry

avatar image
0

Answer by holyfot · Oct 07, 2020 at 09:44 AM

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
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image IndieFist · Oct 14, 2020 at 09:21 AM 0
Share

im testing this, but door start rotating and never stop xD ok, i found the problem, instead of check rotation.z i need to check the rotation axis used. now works, thanks for sharing

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

7 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

-= Time.deltaTime 1 Answer

Rotating camera not working? 0 Answers

Quaternion does not work 0 Answers

I'm adapting the portals from Brackeys to VR, how to stop Z axis from rotating in render texture? 0 Answers

Best Method to Rotate Camera around a GameObject while looking at another? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges