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
0
Question by vortexofdoom · Jan 16, 2014 at 07:31 AM · rotation3rd person controller3rd person camera

Using gamepad triggers to control 3rd person camera

I'm working on a control scheme that has movement that basically matches up well enough with the default 3rd person controller that I'm trying to roll with it to save a bit of time and have a well-functioning script for the prototype rather than something janky, since this particular game relies entirely on motion feeling natural. The only issue I have is that I want to make the analog triggers control the camera's rotation and set a much longer timer for the camera moving back around to the back of the player. Basically, I just want it to rotate around the player and MAYBE have it so that after a long enough time idle, it will move around back again, although that is far from necessary.

I know it makes me sound like a total noob, but the biggest issue I'm having is I can't read the code well enough to determine where exactly I'd have to change it from an automated action to one that relies on input. I've looked at tons of tutorials, but everything seems to be focused toward full camera control, usually with the mouse, and since the camera has the type of movement that I want already, it seems silly to try to fish the lines out of those tutorials when everything else works as intended so far. The camera script as I have it is here:

 using UnityEngine;
 using System.Collections;
 
 public class ThirdPersonCamera : MonoBehaviour 
 {
     public Transform cameraTransform;
     private Transform _target;
     
     // The distance in the x-z plane to the target
     
     public float distance= 7.0f;
     
     // the height we want the camera to be above the target
     public float height= 3.0f;
     
     public float angularSmoothLag= 0.3f;
     public float angularMaxSpeed= 15.0f;
     
     public float heightSmoothLag= 0.3f;
     
     public float snapSmoothLag= 0.2f;
     public float snapMaxSpeed= 720.0f;
     
     public float clampHeadPositionScreenSpace= 0.75f;
     
     public float lockCameraTimeout= 0.2f;
     
     private Vector3 headOffset= Vector3.zero;
     private Vector3 centerOffset= Vector3.zero;
     
     private float heightVelocity= 0.0f;
     private float angleVelocity= 0.0f;
     private bool snap= false;
     private ThirdPersonController controller;
     private float targetHeight= 100000.0f; 
     
     void  Awake (){
         
         if(!cameraTransform && Camera.main)
             cameraTransform = Camera.main.transform;
         if(!cameraTransform) {
             Debug.Log("Please assign a camera to the ThirdPersonCamera script.");
             enabled = false;    
         }
                 
             
         _target = transform;
         if (_target)
         {
             controller = _target.GetComponent<ThirdPersonController>();
         }
         
         if (controller)
         {
             CharacterController characterController = _target.GetComponent<CharacterController>();
             centerOffset = characterController.bounds.center - _target.position;
             headOffset = centerOffset;
             headOffset.y = characterController.bounds.max.y - _target.position.y;
         }
         else
             Debug.Log("Please assign a target to the camera that has a ThirdPersonController script attached.");
     
         
         Cut(_target, centerOffset);
     }
     
     void  DebugDrawStuff (){
         Debug.DrawLine(_target.position, _target.position + headOffset);
     
     }
     
     public float AngleDistance ( float a ,   float b  ){
         a = Mathf.Repeat(a, 360);
         b = Mathf.Repeat(b, 360);
         
         return Mathf.Abs(b - a);
     }
     
     void  Apply ( Transform dummyTarget ,   Vector3 dummyCenter  ){
         // Early out if we don't have a target
         if (!controller)
             return;
         
         Vector3 targetCenter= _target.position + centerOffset;
         Vector3 targetHead= _target.position + headOffset;
     
     //    DebugDrawStuff();
     
         // Calculate the current & target rotation angles
         float originalTargetAngle= _target.eulerAngles.y;
         float currentAngle= cameraTransform.eulerAngles.y;
     
         // Adjust real target angle when camera is locked
         float targetAngle= originalTargetAngle; 
         
         // When pressing Fire2 (alt) the camera will snap to the target direction real quick.
         // It will stop snapping when it reaches the target
         if (Input.GetButton("LockOn"))
             snap = true;
         
         if (snap)
         {
             // We are close to the target, so we can stop snapping now!
             if (AngleDistance (currentAngle, originalTargetAngle) < 3.0f)
                 snap = false;
             
             currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, snapSmoothLag, snapMaxSpeed);
         }
         // Normal camera motion
         else
         {
             if (controller.GetLockCameraTimer () < lockCameraTimeout)
             {
                 targetAngle = currentAngle;
             }
     
             // Lock the camera when moving backwards!
             // * It is really confusing to do 180 degree spins when turning around.
             if (AngleDistance (currentAngle, targetAngle) > 160 && controller.IsMovingBackwards ())
                 targetAngle += 180;
     
             currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, angularSmoothLag, angularMaxSpeed);
         }
     
     
         // When jumping don't move camera upwards but only down!
         if (controller.IsJumping ())
         {
             // We'd be moving the camera upwards, do that only if it's really high
             float newTargetHeight= targetCenter.y + height;
             if (newTargetHeight < targetHeight || newTargetHeight - targetHeight > 5)
                 targetHeight = targetCenter.y + height;
         }
         // When walking always update the target height
         else
         {
             targetHeight = targetCenter.y + height;
         }
     
         // Damp the height
         float currentHeight= cameraTransform.position.y;
         currentHeight = Mathf.SmoothDamp (currentHeight, targetHeight, ref heightVelocity, heightSmoothLag);
     
         // Convert the angle into a rotation, by which we then reposition the camera
         Quaternion currentRotation= Quaternion.Euler (0, currentAngle, 0);
         
         // Set the position of the camera on the x-z plane to:
         // distance meters behind the target
         cameraTransform.position = targetCenter;
         cameraTransform.position += currentRotation * Vector3.back * distance;
     
         Vector3 tempCameraTransformPos=cameraTransform.position;
             
         tempCameraTransformPos.y=currentHeight;
         cameraTransform.position=tempCameraTransformPos;
         
         // Always look at the target    
         SetUpRotation(targetCenter, targetHead);
     }
     
     void  LateUpdate (){
         Apply (transform, Vector3.zero);
     }
     
     void  Cut ( Transform dummyTarget ,   Vector3 dummyCenter  ){
         float oldHeightSmooth= heightSmoothLag;
         float oldSnapMaxSpeed= snapMaxSpeed;
         float oldSnapSmooth= snapSmoothLag;
         
         snapMaxSpeed = 10000;
         snapSmoothLag = 0.001f;
         heightSmoothLag = 0.001f;
         
         snap = true;
         Apply (transform, Vector3.zero);
         
         heightSmoothLag = oldHeightSmooth;
         snapMaxSpeed = oldSnapMaxSpeed;
         snapSmoothLag = oldSnapSmooth;
     }
     
     void  SetUpRotation ( Vector3 centerPos ,   Vector3 headPos  ){
         // Now it's getting hairy. The devil is in the details here, the big issue is jumping of course.
         // * When jumping up and down we don't want to center the guy in screen space.
         //  This is important to give a feel for how high you jump and avoiding large camera movements.
         //   
         // * At the same time we dont want him to ever go out of screen and we want all rotations to be totally smooth.
         //
         // So here is what we will do:
         //
         // 1. We first find the rotation around the y axis. Thus he is always centered on the y-axis
         // 2. When grounded we make him be centered
         // 3. When jumping we keep the camera rotation but rotate the camera to get him back into view if his head is above some threshold
         // 4. When landing we smoothly interpolate towards centering him on screen
         Vector3 cameraPos= cameraTransform.position;
         Vector3 offsetToCenter= centerPos - cameraPos;
         
         // Generate base rotation only around y-axis
         Quaternion yRotation= Quaternion.LookRotation(new Vector3(offsetToCenter.x, 0, offsetToCenter.z));
     
         Vector3 relativeOffset= Vector3.forward * distance + Vector3.down * height;
         cameraTransform.rotation = yRotation * Quaternion.LookRotation(relativeOffset);
     
         // Calculate the projected center position and top position in world space
         Ray centerRay= cameraTransform.camera.ViewportPointToRay(new Vector3(.5f, 0.5f, 1f));
         Ray topRay= cameraTransform.camera.ViewportPointToRay(new Vector3(.5f, clampHeadPositionScreenSpace, 1f));
     
         Vector3 centerRayPos= centerRay.GetPoint(distance);
         Vector3 topRayPos= topRay.GetPoint(distance);
         
         float centerToTopAngle= Vector3.Angle(centerRay.direction, topRay.direction);
         
         float heightToAngle= centerToTopAngle / (centerRayPos.y - topRayPos.y);
     
         float extraLookAngle= heightToAngle * (centerRayPos.y - centerPos.y);
         if (extraLookAngle < centerToTopAngle)
         {
             extraLookAngle = 0;
         }
         else
         {
             extraLookAngle = extraLookAngle - centerToTopAngle;
             cameraTransform.rotation *= Quaternion.Euler(-extraLookAngle, 0, 0);
         }
     }
     
     public Vector3 GetCenterOffset (){
         return centerOffset;
     }
 
 }

Any help is appreciated.

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

Answer by thedalek247 · Nov 26, 2014 at 09:06 PM

Have you tried using input.Getbutton? you could use that then configure it so that if the bumper is pressed the camera rotates 90 degrees on the y axis,that's basically what the code does,just automatically.

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 meat5000 · Nov 26, 2014 at 09:07 PM

You will need to set up the Z-Axis in the Input Manager and then use this

http://docs.unity3d.com/ScriptReference/Input.GetAxis.html to read it.

According to Windows, gamepad triggers not not buttons but the Z-Axis.

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

20 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

Related Questions

How to make the character move and rotate where the camera is facing (3rd person) 0 Answers

How to get JUST the y rotation of an object? 3 Answers

transform.rotation and localRotation automatically reset after rotating. 1 Answer

How to move player in direction where the camera is aiming ? 1 Answer

Set Character's Rotation 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