Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
1
Question by Tobinator007 · Aug 18, 2013 at 04:13 PM · camera rotatemove an objectfunction update

Rubber banding camera (help!)

Okay, so this code segment is supposed to move the camera (which is the otherGameObject) after I select the object to which the script is attached.

It works perfectly about 2/3s of the time. The other time, it will create what seems to be what seems to be a small box around the object out of which I can't move the camera.

Any thoughts? I can't imagine its update being called too slowly.

Updated: Full code below

 public     var otherGameObject : GameObject;
 private var moveTheCamera = false;
 public     var smooth : float;
 private var targetPosition : Vector3;
 private var targetRotation : Quaternion;
 private var targetPosition2 : Vector3;
 
 function Awake () {
 
 }
 function Start () {
 
 }
 
 function Update () {
     
     if  ((targetPosition2.z - otherGameObject.transform.position.z < .05) && (targetPosition2.z - otherGameObject.transform.position.z > 0))
         {
         moveTheCamera = false;
         }
 
     else if (moveTheCamera == true) 
     {
         if (Mathf.Approximately(transform.eulerAngles.y, 0))
             {
             targetPosition2 = (transform.position + (targetPosition * -5));
             }
         if (Mathf.Approximately(transform.eulerAngles.y, 180))
             {
             targetPosition2 = (transform.position + (targetPosition * -5));
             }
         
         otherGameObject.transform.position = Vector3.Lerp(otherGameObject.transform.position, targetPosition2, smooth * Time.deltaTime);
         otherGameObject.transform.rotation = Quaternion.Slerp(otherGameObject.transform.rotation, targetRotation, smooth * Time.deltaTime);
         }
     
 
 }
 
 function OnMouseDown () 
     {
         moveTheCamera = true;
         targetPosition = Vector3.forward;
         targetRotation = Quaternion.Euler(otherGameObject.transform.eulerAngles.x, transform.eulerAngles.y, otherGameObject.transform.eulerAngles.z);
         Debug.Log(targetRotation);
         Debug.Log(targetPosition);    
     }
 
 function OnMouseUp()
     {    
         //moveTheCamera = false;
         Debug.Log(targetPosition2.z);
         Debug.Log(otherGameObject.transform.position.z);
         Debug.Log(targetPosition2.z - otherGameObject.transform.position.z);
         Debug.Log(Mathf.Abs(targetPosition2.z - otherGameObject.transform.position.z));
     }
 
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
3
Best Answer

Answer by aldonaletto · Aug 18, 2013 at 07:58 PM

I really didn't get what your script is trying to do, but reading eulerAngles isn't reliable: it may return values totally different from what you expect. Anyway, this seems too complicated - you could simply place an empty game object with the desired position and rotation, assign it to target and let the camera lerp to it continuously:

 var target: Transform; // assign the target empty to this variable
 var smooth: float = 3.0;

 function Update () {
   if (target){ // if some target defined, lerp to it:
     otherGameObject.transform.position = Vector3.Lerp(otherGameObject.transform.position, target.position, smooth * Time.deltaTime);
     otherGameObject.transform.rotation = Quaternion.Slerp(otherGameObject.transform.rotation, target.rotation, smooth * Time.deltaTime);
   }
 }

EDITED: Ok, so you want the camera to get free after reaching the desired position. In this case, I would use a trick similar to yours: calculate the back position, lerp to it and let the camera free once the position is reached - but I would use the object's forward direction to guide the rotation, and the distance to the target in order to finish the auto movement, like this:

 function Update () {
     if (moveTheCamera){
         // target position is 5 units behind target object:
         targetPosition2 = transform.position - 5 * transform.forward;
         // target rotation is the same of the target object:
         targetRotation = transform.rotation;
         otherGameObject.transform.position = Vector3.Lerp(otherGameObject.transform.position, targetPosition2, smooth * Time.deltaTime);
         otherGameObject.transform.rotation = Quaternion.Slerp(otherGameObject.transform.rotation, targetRotation, smooth * Time.deltaTime);
     }
     // free the camera when it gets closer than 0.05:
     if (Vector3.Distance(targetPosition2, otherGameObject.transform.position) < .05){
         moveTheCamera = false;
     }
 }

I suppose that this script is attached to each possible target, and moveTheCamera is set in the desired object in order to "attract" the camera.

Comment
Add comment · Show 4 · 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 Tobinator007 · Aug 19, 2013 at 12:23 AM 0
Share

Hey thanks for the reply Aldonaletto! I guess I didn't do a good job explaining why I wanted this script. Our game the units will be arranged like a chess board (which means the units will be rotated either 0 or 180 on the Y).

I want this script to tell the camera to move behind the unit selected. So it sets a targetposition behind the unit, and then the camera flies there. The problem is that sometimes the "fly there" script doesn't end, so when you try and free-move the camera away from the select unit, it gets "rubber banded" back to the target position.

Are you suggesting putting a child empty gameobject behind each unit and use that as the target position? The problem is that I don't want to change the "zoom" of the camera as it flies.

Thanks, and I hope this makes sense. I'm trying to self-$$anonymous$$ch here, to varying degrees of success. :)

avatar image aldonaletto · Aug 19, 2013 at 01:38 AM 0
Share

I edited my answer to include a code that may do what you want (I hope)

avatar image Tobinator007 · Aug 19, 2013 at 01:52 AM 0
Share

Thanks aldonaletto. As I alluded to my comment to meat5000, I've editted my original question to include my full code.

Three thoughts/questions on your answer:

  1. The use of transform.forward didn't seem to work when I first used it in my code(which is why I changed it to check the rotation of the object). Is there an easier way to do this?

  2. I've avoided using the targetRotation = transform.rotation code because I was afraid of changing the 'angle' of the camera . It's currently at a fixed 40 degree angle from the seperate free-move script.

  3. The vector 3 distance sounds promissing, is there something about my use of the float (z position) that makes it unreliable? The script DOES free the camera 2 out of 3 times, so I know it's working - what's the difference using the vector3.distance method?

Also, if I could upvote you, I would! I'll upvote as soon as I earn the reputation points. Thanks for putting in the time with a novice.

avatar image aldonaletto · Aug 19, 2013 at 03:42 PM 0
Share

1- transform.forward works fine if the object's forward direction points in its local Z - many 3D editors scramble the axes, and frequently we import models whose forward direction is aligned to X or Y. If your models all face the X direction, for instance, use transform.right ins$$anonymous$$d of transform.forward;

2- You're right: assu$$anonymous$$g the object rotation may be a disaster when the object has scrambled axes or when you want to have a particular inclination. If your solution is working fine (I mean: if it's looking at the desired direction), keep it - rotations are too tricky to abandon a solution that's working!

3- $$anonymous$$easuring things directly along the axes is a bad idea in a 3D space due to the object rotation: the Z axis may be aligned to any direction relative to the object. In this particular case, you're only checking whether the Z coordinate is closer than -0.05 to the target position - if it's co$$anonymous$$g from the other side, the loop will never end. Vector3.Distance evaluates the unsigned distance in any direction, thus you would not have this problem.

avatar image
0

Answer by meat5000 · Aug 19, 2013 at 12:44 AM

You may be getting stuck in moveTheCamera == true condition and so the Lerp is locking you in to target.position

As time has progressed and t >= 1 your Lerp is locked at target.position as t=1;

Your use of Mathf.Approximately and eulerAngles could explain why this happens only some of the time. When the numbers are slightly out of your bounds you get locked in.

Avoid approximation and use something other than eulerAngles. Alternatively, detect when the Lerp is completed (i.e when t=1) and manually set

 moveTheCamera = false;

within the braces of

 else if (moveTheCamera == true)
Comment
Add comment · Show 4 · 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 Tobinator007 · Aug 19, 2013 at 01:16 AM 0
Share

I suspect you are correct that I am getting stuck in the "true" condition for moveTheCamera.

I don't think it relates to the use of eulerAngles, as this script also got stuck with lerp before I added the support for units "on the other side" of the chess board.

I'd love to detect when the Lerp is complete (in fact, that's what I'm trying to do with the first if statement). Can you offer other suggestions as to how to detect this?

Again, as a novice, I appreciate both your patience and your help. I also realized I only posted a portion of my code in the original answer, I'm editing to include the full script.

avatar image meat5000 ♦ · Aug 19, 2013 at 08:12 AM 0
Share

The Lerp is complete when the Lerp 't' factor is 1.

 static function Lerp(from: Vector3, to: Vector3, t: float): Vector3;

Despite whatever anyone puts into the t field, Lerp only works between t = 0 -> 1. When t = 0 Lerp returns the From field. When it is 1 it returns the To field and a value in between will give you a value/Vector3 between From and To. The Lerp is complete when, in your case, the object position = To or when t = 1.

There are other conditions your could use, for example, when the camera has arrived at its position the speed/velocity should be 0. You could even use some kind of Position Array (a procedural script or a predefined table) to store all the positions of the camera as there are a set amount. You can even reference them by index in that scenario.

avatar image Tobinator007 · Aug 19, 2013 at 06:05 PM 0
Share

Thanks for the help meat5k - I'll upvote you when I get the rep. You were very helpful!

avatar image meat5000 ♦ · Aug 19, 2013 at 06:21 PM 0
Share

You are welcome, good Sir

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

17 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

Related Questions

Move speed decrease stoping object problem. 1 Answer

Sync Camera and Object 1 Answer

Endless runner, road segments spawn speed 0 Answers

Camera Rotation Script Totally Screwed Up 1 Answer

Stop a enemy by pointing a light at it. 4 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