Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
avatar image
0
Question by GamesWerfer · May 08, 2020 at 05:28 AM · camerarotationtransformvector3

nullifying targetObject after a Smooth LookAt Transition

A bit of context first, I'm making a game where the main camera is fixed at a position and it will look at different game objects depending on the input of the player. In this scene I have 3 game objects and the player would input either A and D to transition the camera perspective to the object on the left or right.

alt text

I managed to create a smooth transition based on a answer from the unity forums (https://forum.unity.com/threads/transform-lookat-smooth-transition-instead-of-instant-snapping.522119/) and I was able to achieve the smooth transition I wanted. However I face a problem now: the function to do the rotation keeps getting called in the update function.

Heres the code: using System.Collections; using System.Collections.Generic; using UnityEngine;

 public class CameraBehaviour : MonoBehaviour
 {
     // Start is called before the first frame update
 
     Vector3 targetDirection;
     private Transform targetObject = null;
     private float speed;
 
     private float distance;
 
     void Start()
     {
         speed = 5f;
         targetObject = null;
         distance = 0;
     }
 
     // Update is called once per frame
     void Update()
     {
         if(targetObject != null)
         {
             SmoothTransition();
             Debug.Log("SmoothTransition() is being called");
 
             checkIfDone();
         }
     }
 
     public void TransitionTo(Transform targetObject)
     {
         this.targetObject = targetObject;
 
         distance = Vector3.Distance(targetObject.position, transform.position);
     }
 
     private void SmoothTransition()
     {
         Vector3 targetDir = targetObject.position - transform.position;
 
 
         targetDir.y = 0;
         float step = speed * Time.deltaTime;
 
         Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0f);
 
         transform.rotation = Quaternion.LookRotation(newDirection);
 
         
     }
 
     private void checkIfDone()
     {
         RaycastHit hit;
 
         Debug.DrawRay(transform.position, transform.forward, Color.red);
         if (Physics.Raycast(transform.position, transform.forward, out hit, distance))
         {
             Debug.Log(transform.gameObject.name + "is hit");
 
 
             if (hit.transform.Equals(targetObject))
             {
                 targetObject = null;
                 Debug.Log("TargetObject has been nullified");
             }
         }
     }
 }
 

The function keeps getting called because of the condition in the update function. My reason for putting that condition is to make sure the function won't be called all the time and would optimize the game. In order to make the condition false, there would be a function that would use raycasting to check if the camera is already looking at the targetObject. If it is already looking at the targetObject, then targetObject would be null.

However it seems that the targetObject is not nulled out when i tested the code. My question is how do I correctly make sure that that the camera is looking at the targetObject?

null-problem.png (321.8 kB)
Comment
Add comment
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

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by icehex · May 08, 2020 at 06:40 AM

Hi @GamesWerfer instead of using a raycast to see if you're pointing at the camera, why not just see if the forward vector is close enough to the target vector? Try this:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class CameraBehavior : MonoBehaviour
 {
     // Start is called before the first frame update
 
     Vector3 targetDirection;
     private Transform targetObject;
     private float speed;
 
     private float distance;
 
     void Start()
     {
         speed = 0.05f;
         distance = 0;
 
     }
 
     // Update is called once per frame
     void Update()
     {
 
         if (targetObject != null)
         {
             SmoothTransition();
             Debug.Log("SmoothTransition() is being called");
 
         }
     }
 
     public void TransitionTo(Transform targetObject)
     {
         this.targetObject = targetObject;
 
         distance = Vector3.Distance(targetObject.position, transform.position);
     }
 
     private void SmoothTransition()
     {
         Vector3 targetDir = targetObject.position - transform.position;
 
         targetDir.y = 0;
         targetDir = targetDir.normalized;
 
         if (Mathf.Abs(targetDir.x - transform.forward.x) < 0.01f && Mathf.Abs(targetDir.z - transform.forward.z) < 0.01f)
         {
             Debug.Log("No more rotation needed");
             targetObject = null;
 
             return;
         }
 
         float step = speed * Time.deltaTime;
 
         Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0f);
 
         transform.rotation = Quaternion.LookRotation(newDirection);
 
     }
 }

Comment
Add comment · Show 2 · 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 GamesWerfer · May 09, 2020 at 05:06 AM 0
Share

This worked, it nulled out the targetObject variable after completing the rotation. Although it seems that the smoothTransition() function was still called once after nulling targetObject.

I kind of don't understand the math of your solution. So essentially I just need to calculate the current forward vector of the camera and compare it with the target direction vector?

Thank you very much for the solution!

avatar image icehex GamesWerfer · May 09, 2020 at 08:49 AM 0
Share

Yea the code you had basically takes your object's direction and tries to align it with the direction to your target. So the maths there just check the target direction's x and z components versus your object's transform. Once your screen's 'aim' lines up with your target, the x and z components should be zero (or near to zero given $$anonymous$$ors errors).

avatar image
0

Answer by GamesWerfer · May 09, 2020 at 05:23 AM

I actually did more testing and found out that one line of code that I copied from the forums is the reason why my checkIfDone() function isn't working. It seems because I set my targetDir's y component to 0, the raycast would miss the exact position of the targetObject. But I would like to thank @icehex again for providing me with a solution

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class CameraBehaviour : MonoBehaviour
 {
     // Start is called before the first frame update
 
     Vector3 targetDirection;
     private Transform targetObject = null;
     private float speed;
 
     private float distance;
 
     void Start()
     {
         speed = 5f;
         targetObject = null;
         distance = 0;
     }
 
     // Update is called once per frame
     void Update()
     {
         if(targetObject != null)
         {
             SmoothTransition();
             Debug.Log("SmoothTransition() is being called");
 
             checkIfDone();
         }
     }
 
     public void TransitionTo(Transform targetObject)
     {
         this.targetObject = targetObject;
 
         distance = Vector3.Distance(targetObject.position, transform.position);
     }
 
     private void SmoothTransition()
     {
         Vector3 targetDir = targetObject.position - transform.position;
 
 
         //targetDir.y = 0;
         targetDir = targetDir.normalized;
         /*
         if(Mathf.Abs(targetDir.x - transform.forward.x) < 0.01f && Mathf.Abs(targetDir.z - transform.forward.z) < 0.01f)
         {
             Debug.Log("No More Rotation Needed");
             targetObject = null;
 
             return;
         }*/
 
         float step = speed * Time.deltaTime;
 
         Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0f);
 
         transform.rotation = Quaternion.LookRotation(newDirection);
 
         
     }
 
     private void checkIfDone()
     {
         RaycastHit hit;
 
         Debug.DrawRay(transform.position, transform.forward, Color.red);
         if (Physics.Raycast(transform.position, transform.forward, out hit, distance))
         {
             Debug.Log(transform.gameObject.name + "is hit");
 
 
             if (hit.transform.Equals(targetObject))
             {
                 targetObject = null;
                 Debug.Log("TargetObject has been nullified");
             }
         }
     }
 }



Comment
Add comment · 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

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

253 People are following this question.

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

Related Questions

Keep camera at certain distance from character when rotating 3 Answers

Player rotation = Camera Rotation 0 Answers

How do i lock the position of the camera above the player relative to the origin point? 0 Answers

How do I set a child object to not rotate if the parent WILL be rotating? 1 Answer

Workaround for Quaternion.eulerAngles 360 Degree Limit? 1 Answer


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