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 /
  • Help Room /
avatar image
0
Question by oltranzista · Dec 16, 2015 at 02:54 PM · positioncamera-movementcamera rotatepositioning

Third Person Camera - primary orbit script logic keeps overriding other position logic

I have a third person camera script that allows the player to orbit the character, sort of like an RPG. I'm trying to add a convenience command (called hOrbitSnapInput) to allow the player to press a button to have the camera "reset" behind the player.

My problem is when the player tries to execute the hOrbitSnapInput. It will change the position of the camera for a split second (probably just one frame?) and then return right back to its previous position.

Here's a video of what's going on: https://youtu.be/uP91hr_FeNc.

  • At about the 0:11 second mark you see the camera change position and switch right back to it's original positon.

  • At 0:21 I add logic to stop executing the Update() method after I send the orbit snap input to make sure that my orbit snap input logic did work at 0:31.

Here is my camera script:

 public class CameraOrbit : MonoBehaviour
 {
     public Transform player;
     public float distance = 5.0f;
     private float distanceFromGround = 1.5f;
     float xAxis;
     float yAxis;
     bool hOrbitSnapInput;
     bool snapped = false;
     const float speed = 5.0f;
     public float minVerticalAngle = -15f;
     public float maxVerticalAngle = 60f;
 
     void Update()
     {
         //if (hOrbitSnapInput)
         //    return;
 
         var behindPlayerPosition = player.position + player.forward * -distance;
         hOrbitSnapInput = Input.GetButtonDown("X360_RightStickClick");
         Debug.DrawLine(player.position, behindPlayerPosition, Color.red);
 
         if (hOrbitSnapInput)
         {
             xAxis = 0;
             yAxis = 0;
 
             // Camera position
             transform.position = 
                 behindPlayerPosition + new Vector3(0.0f, distanceFromGround, 0.0f);
 
             transform.LookAt(player);
         }
         else
         {
             xAxis += Input.GetAxis("X360_RightStickX") * speed;
             yAxis -= Input.GetAxis("X360_RightStickY") * speed;
 
             // Restrict camera vertical rotation movement
             yAxis = Mathf.Clamp(yAxis, minVerticalAngle, maxVerticalAngle);
 
             var rotation = Quaternion.Euler(yAxis, xAxis, 0.0f);
 
             // Camera position
             transform.position = 
                 player.position + rotation * new Vector3(0.0f, distanceFromGround, -distance);
 
             // Camera lookat rotation
             transform.rotation = rotation;
         }
     }
 }
 

Here is my camera setup: alt text

Here is my player setup: alt text

player.png (72.4 kB)
camera.png (60.7 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
0
Best Answer

Answer by wibble82 · Dec 16, 2015 at 03:15 PM

Well from looking at it, I see when you reset the camera you do 2 things:

  • You set the xAxis and yAxis values to 0

  • You force the camera to a specific location

However you then continue as normal with some different maths in the normal case the following frames.

This would be fine if the act of setting 'xAxis' and 'yAxis' to 0 had exactly the same result as you forcing the camera to the 'behind' position. If that were true, then when the normal orbit took over it'd look exactly right.

The problem is that I doubt very much if that's the case. I can't tell you exactly what to write from looking at it, but I would recommend you structure your code more like this:

 void Update()
 {
 
     //first we will do our 'controls' logic, which modifies our xAxis and yAxis values based on what the player does
     hOrbitSnapInput = Input.GetButtonDown("X360_RightStickClick");
     if (hOrbitSnapInput)
     {
         //you will need to work out what the right values are for xAxis and yAxis to 'reset' nicely
         xAxis = 0;
         yAxis = 0;
     }
     else
     {
         //update xAxis and yAxis based on input
         xAxis += Input.GetAxis("X360_RightStickX") * speed;
         yAxis -= Input.GetAxis("X360_RightStickY") * speed;
         yAxis = Mathf.Clamp(yAxis, minVerticalAngle, maxVerticalAngle);
     }
 
     //now that xAxis and yAxis are updated, we will use them to generate a new transform
     var rotation = Quaternion.Euler(yAxis, xAxis, 0.0f);
  
     // Camera position
     transform.position = player.position + rotation * new Vector3(0.0f, distanceFromGround, -distance);
  
     // Camera lookat rotation
     transform.rotation = rotation;
 }

The reason I structure it this way is that I have divided your code into 2 sections:

  • The bit that does the controls

  • The math that turns the results of the controls into a camera position

By doing this I've made it impossible for your controls to inadvertently use different maths in different scenarios. You will still need to work out what a nice pair of values to reset xAxis and yAxis to are, but you can at least now be sure that when you do reset them, the controls logic will continue on correctly from whatever you reset them to.

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
avatar image
0

Answer by oltranzista · Dec 17, 2015 at 04:38 AM

Here's what I ended up doing, it seems to work pretty well.

I wish I could understand why the other script wouldn't work, I think I'm missing out on some fundamental understanding on what/how properties can and can't be assigned.

 using UnityEngine;
 
 public class CameraOrbit : MonoBehaviour
 {
     public Transform player;
     public float distance = 5.0f;
     public float minVerticalAngle = -15f;
     public float maxVerticalAngle = 60f;
     float distanceFromGround = 1.5f;
     float xAxis;
     float yAxis;
     const float speed = 5.0f;
     Vector3 originAngle;
 
     void Start()
     {
         originAngle = GetOrthographicTop(player.forward);
     }
 
     void LateUpdate()
     {
         var hOrbitSnapInput = Input.GetButtonDown("X360_RightStickClick");
 
         if (hOrbitSnapInput)
         {
             float cameraAngle = SignedAngle(originAngle, GetOrthographicTop(transform.forward)) * -1;
             float playerAngle = SignedAngle(originAngle, GetOrthographicTop(player.forward));
 
             xAxis = xAxis + playerAngle + cameraAngle;         
             yAxis = 0;
         }
         else
         {
             xAxis += Input.GetAxis("X360_RightStickX") * speed;
             yAxis -= Input.GetAxis("X360_RightStickY") * speed;
 
             // Restrict camera vertical rotation movement
             yAxis = Mathf.Clamp(yAxis, minVerticalAngle, maxVerticalAngle);
         }
 
         var rotation = Quaternion.Euler(yAxis, xAxis, 0.0f);
 
         // Camera "lookat" rotation
         transform.rotation = rotation;
 
         // Camera position
         transform.position = player.position + rotation * new Vector3(0.0f, distanceFromGround, -distance);
     }
 
     float SignedAngle(Vector3 a, Vector3 b)
     {
         var angle = Vector3.Angle(a, b);
 
         // assume the sign of the cross product's Y component:
         return angle * Mathf.Sign(Vector3.Cross(a, b).y);
     }
 
     Vector3 GetOrthographicTop(Vector3 vector)
     {
         return new Vector3(vector.x, 0, vector.z);
     }
 }
 
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

34 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

Related Questions

How to get camera to face an object automatically upon teleportation?,How do I get the camera to face an object after teleportation? 0 Answers

how to jump my character to fixed distance 0 Answers

Assinging new coordinates (position) in Unity to imported assets/objects from Rhino 0 Answers

Enemy's set position is incorrect? 1 Answer

Click on different objects to move the camera 2 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