• 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 PegasiStudios · Jun 13, 2018 at 07:32 AM · cameraraycastcamera-movementplatformercamera rotation

How to prevent camera from clipping through walls with raycasts?

I have a third person camera for a 3D platformer, and it goes through terrain easily with nothing stopping it. I initially tried the method of using a rigidbody and sphere collider, but that just makes the camera very clunky.

I'm know little about raycasts, so what should I do to fix this issue?

Here is my code for the camera:

 public bool AutoTrack = false;
 
     public float InitialPosition = 9.3f;
 
     public float YSensitivity = 45.0f;
     public float XSensitivity = 45.0f;
 
     public float MinDistance = 5.0f;
     public float MaxDistance = 15.0f;
 
     public float MinHeight = 2.0f;
     public float MaxHeight = 8.0f;
 
     public float MinAngle = 10.0f;
     public float MaxAngle = 30.0f;
 
     public float MinDampWeight = 0.75f;
     public float MaxDampWeight = 0.3f;
 
     public float MinDropDistance = 10.0f;
     public float MaxDropDistance = 25.0f;
 
     public float MinDropRotation = 0.0f;
     public float MaxDropRotation = 60.0f;
 
     public float MinMaximumJumpHeight = 5.0f;
     public float MaxMaximumJumpHeight = 8.0f;
 
     public float MinMaxHeightAdjustment = 5.0f;
     public float MaxMaxHeightAdjustment = 12.0f;
 
     public Transform target { get; private set; }
     private MarioMachine mario;
     private MarioInput input;
     private SuperCharacterController controller;
 
     // Lerp value for Distance, Height and Angle between 0 and 1
     private float currentCameraPosition;
     private float currentRotationHorizontal;
     private float currentRotationVertical;
 
     private float currentRotationVelocity;
 
     private Vector3 liftoffPoint;
     private Vector3 verticalPosition;
     private Vector3 currentDampVelocity;
 
     private Vector3 planarPosition;
     private Vector3 planarDampVelocity;
     private bool planarDamping = false;
 
     private Vector3 cameraShakePosition;
     private Vector3 constantShakePosition;
 
     private IEnumerator shakeCoroutine;
 
     void Start () {
         currentCameraPosition = InitialPosition;
 
         target = GameObject.FindWithTag("Player").transform;
 
         input = target.GetComponent<MarioInput>();
         mario = target.GetComponent<MarioMachine>();
         controller = target.GetComponent<SuperCharacterController>();
 
         currentRotationHorizontal = mario.InitialRotation;
 
         var height = Mathf.Lerp(MinHeight, MaxHeight, currentCameraPosition);
 
         verticalPosition = Math3d.ProjectPointOnLine(Vector3.zero, controller.up, target.position + height * controller.up);
 
         StartCoroutine(ConstantShake());
     }
 
     float currentShakeMagnitude;
 
     public void ConstantShake(float magnitude)
     {
         currentShakeMagnitude = Mathf.Max(currentShakeMagnitude, magnitude);
     }
 
         public void Shake(float magnitude, float speed, float duration)
     {
         StopShake();
         shakeCoroutine = CameraShake(magnitude, speed, duration, true);
         StartCoroutine(shakeCoroutine);
     }
 
     public void StopShake()
     {
         if (shakeCoroutine != null)
             StopCoroutine(shakeCoroutine);
     }
 
     IEnumerator CameraShake(float magnitude, float speed, float duration, bool damp)
     {
         cameraShakePosition = Vector3.zero;
 
         Vector3 targetPosition = cameraShakePosition;
 
         float shakeStartTime = Time.time;
 
         while (!SuperMath.Timer(shakeStartTime, duration))
         {
             cameraShakePosition = Vector3.MoveTowards(cameraShakePosition, targetPosition, speed * Time.deltaTime);
 
             float magModifier = 1.0f - Mathf.InverseLerp(shakeStartTime, shakeStartTime + duration, Time.time);
 
             if (cameraShakePosition == targetPosition)
             {
                 targetPosition = Vector3.zero + Random.insideUnitSphere * magnitude * magModifier;
             }
 
             yield return 0;
         }
 
         while (cameraShakePosition != Vector3.zero)
         {
             cameraShakePosition = Vector3.MoveTowards(cameraShakePosition, Vector3.zero, speed * Time.deltaTime);
 
             yield return 0;
         }
     }
 
     IEnumerator ConstantShake()
     {
         constantShakePosition = Vector3.zero;
 
         Vector3 targetPosition = constantShakePosition;
 
         while (true)
         {
             if (currentShakeMagnitude != 0)
             {
                 constantShakePosition = Vector3.MoveTowards(constantShakePosition, targetPosition, 10.0f * Time.deltaTime);
 
                 if (constantShakePosition == targetPosition)
                 {
                     targetPosition = Vector3.zero + Random.insideUnitSphere * currentShakeMagnitude;
                 }
             }
             else
             {
                 constantShakePosition = Vector3.MoveTowards(constantShakePosition, Vector3.zero, 10.0f * Time.deltaTime);
             }
 
             yield return 0;
         }
     }
 
     void LateUpdate () {
 
         var height = Mathf.Lerp(MinHeight, MaxHeight, currentCameraPosition);
         var maxHeight = Mathf.Lerp(MinMaximumJumpHeight, MaxMaximumJumpHeight, currentCameraPosition);
         var maxHeightAdjustment = Mathf.Lerp(MinMaxHeightAdjustment, MaxMaxHeightAdjustment, currentCameraPosition);
         var distance = Mathf.Lerp(MinDistance, MaxDistance, currentCameraPosition);
         var angle = Mathf.Lerp(MinAngle, MaxAngle, currentCameraPosition);
         var weight = Mathf.Lerp(MinDampWeight, MaxDampWeight, currentCameraPosition);
 
         Vector3 targetPoint = target.position;
 
         if (mario.StateCompare(MarioMachine.MarioStates.Hang) || mario.StateCompare(MarioMachine.MarioStates.Climb))
         {
             targetPoint = mario.ClimbTarget();
 
             if (!planarDamping)
             {
                 SetPlanarDamping(true);
             }
         }
         else
         {
             if (planarDamping)
             {
                 SetPlanarDamping(false);
             }
         }
 
         if (!mario.Airborn())
         {
             liftoffPoint = targetPoint;
 
             verticalPosition = Vector3.SmoothDamp(verticalPosition, Math3d.ProjectPointOnLine(Vector3.zero, controller.up, targetPoint + height * controller.up), ref currentDampVelocity, 0.2f);
 
             currentRotationVertical = Mathf.SmoothDamp(currentRotationVertical, 0, ref currentRotationVelocity, 0.2f);
         }
         else
         { 
             Vector3 groundPosition = Math3d.ProjectPointOnLine(Vector3.zero, controller.up, liftoffPoint);
             Vector3 airPosition = Math3d.ProjectPointOnLine(Vector3.zero, controller.up, targetPoint);
 
             float jumpHeight = Vector3.Distance(groundPosition, airPosition);
 
             var dropRotation = Mathf.Lerp(MinDropRotation, MaxDropRotation, Mathf.InverseLerp(MinDropDistance, MaxDropDistance, jumpHeight));
 
             if (SuperMath.PointAbovePlane(controller.up, liftoffPoint, targetPoint))
             {
                 float extraJumpHeight = 0;
 
                 if (jumpHeight > maxHeight)
                 {
                     extraJumpHeight = Mathf.Clamp(jumpHeight - maxHeight, 0, maxHeightAdjustment);
                 }
 
                 verticalPosition = Vector3.SmoothDamp(verticalPosition, groundPosition + controller.up * ((jumpHeight * weight) + height + extraJumpHeight), ref currentDampVelocity, 0.1f);
             }
             else if (SuperMath.PointAbovePlane(controller.up, liftoffPoint - controller.up * MinDropDistance, targetPoint))
             {
                 verticalPosition = Vector3.SmoothDamp(verticalPosition, Math3d.ProjectPointOnLine(Vector3.zero, controller.up, targetPoint + height * controller.up), ref currentDampVelocity, 0.1f);
 
             }
             else
             {
                 currentRotationVertical = Mathf.SmoothDamp(currentRotationVertical, dropRotation, ref currentRotationVelocity, 0.5f);
             }
         }
 
         Vector3 direction = Math3d.ProjectVectorOnPlane(controller.up, (targetPoint - transform.position).normalized);
 
         float angleAdjustment = Vector3.Angle(direction, Math3d.ProjectVectorOnPlane(controller.up, transform.forward));
 
         if (!AutoTrack)
             angleAdjustment = 0;
 
         angleAdjustment = SuperMath.PointAbovePlane(transform.right, transform.position, targetPoint) ? angleAdjustment : -angleAdjustment;
 
         currentRotationHorizontal = SuperMath.ClampAngle(currentRotationHorizontal - input.Current.CameraInput.x * XSensitivity + angleAdjustment);
 
         transform.rotation = Quaternion.AngleAxis(currentRotationHorizontal, controller.up);
 
         currentCameraPosition = Mathf.Clamp(currentCameraPosition - input.Current.CameraInput.y * YSensitivity, 0, 1);
 
         if (planarDamping)
         {
             planarPosition = Vector3.SmoothDamp(planarPosition, Math3d.ProjectPointOnPlane(controller.up, Vector3.zero, targetPoint), ref planarDampVelocity, 0.2f);
         }
         else
         {
             planarPosition = Math3d.ProjectPointOnPlane(controller.up, Vector3.zero, targetPoint);
         }
 
         transform.position = planarPosition + verticalPosition - transform.forward * distance + cameraShakePosition + constantShakePosition;
 
         transform.rotation = Quaternion.AngleAxis(angle + currentRotationVertical, transform.right) * transform.rotation;
 
         currentShakeMagnitude = 0;
     }
 
     void SetPlanarDamping(bool enabled)
     {
         planarDamping = enabled;
         planarDampVelocity = Vector3.zero;
     }

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

0 Replies

· Add your reply
  • Sort: 

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

169 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

Related Questions

How to make character head face in the direction of where the mouse is pointing in FreeFormCameraRig? 0 Answers

Can you offset the dead zone of Cinemachine's camera from the center? 0 Answers

Moving 3rd person player relative to orbiting camera 1 Answer

Trying to fix bouncy linecast camera collision 1 Answer

how to create a 2d platformer camera with script 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