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 LT23Live · Jan 30, 2015 at 03:38 AM · cameracollisionzoomontriggerstay

Camera Zoom When Camera Touches Geometry

So here is my script I have a box collider around my camera. I have another script to control the zoom of the camera. This script sets that zoom. I have found out it does not detect collision.

 using UnityEngine;
 using System.Collections;
 
 public class AntiClip : MonoBehaviour {
 
     public    bool zoomReady= true;
     public bool gotPreviousZoomState;
     public float previousZoomState;
 
     // Use this for initialization
     void Start () {
     
     }
     
     // Update is called once per frame
     void Update () {
     
     }
 
     void OnTriggerEnter(Collider col)
     {
         print ("clip");
         if (gotPreviousZoomState == false)
         {
             previousZoomState = GetComponent <CameraControl>().distance;
             gotPreviousZoomState = true;
             zoomReady = true;
         }
 
         if (zoomReady == true)
         {
             StartCoroutine (zoom());
         }
     }
 
     void OnTriggerExit (Collider col)
     {
         GetComponent <CameraControl>().distance = previousZoomState;
         gotPreviousZoomState = false;
     }
     IEnumerator zoom()
     {
         zoomReady = false;
         GetComponent <CameraControl>().distance = previousZoomState = GetComponent <CameraControl>().distance- 0.5f;
         yield return new WaitForSeconds (0.01f);
         zoomReady = true;
     }
 }
Comment
Add comment · Show 2
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 Eno-Khaon · Jan 30, 2015 at 05:00 AM 1
Share

Just asking now, does either the camera or the object it's hitting have a rigidbody? If you're using OnTriggerEnter/Exit, I'm guessing that the camera is a trigger.

http://docs.unity3d.com/ScriptReference/$$anonymous$$onoBehaviour.OnCollisionEnter.html

avatar image LT23Live · Jan 30, 2015 at 07:00 PM 0
Share

Neither have a rigid body. I would love to try a different solution if i could. I am just trying to prevent clipping.

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by SomeGuy22 · Mar 07, 2015 at 09:12 PM

I would use Raycasts instead. They can shoot a physics check in a direction and return point information. Unfortunately they only detect in a straight line, but you could use a SphereCast for more complex physics checks. Here's a part of my camera script (it's a modified version of the MouseOrbit.js) Also sorry it's in Javascript :P

          var newDistance = distance;
          
          var p : RaycastHit;
          var l = target.position - transform.position;
          
          
          if (Physics.Raycast(target.position, -l, p, distance, m))
          {
              var d = Vector3.Distance(target.position, p.point);
              //Debug.Log("" + d);
              newDistance = d;
          }
          
          
          Debug.DrawRay(target.position, -l, Color.green);
          
         var rotation = Quaternion.Euler(y, x, 0);
         var position = rotation * Vector3(0.0, 0.0, -newDistance + 0.3) + target.position;
         
         transform.rotation = rotation;
         transform.position = position;
 

Where "m" is the layer mask and x and y are clamped versions of Mouse Input.

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 Cherno · Mar 08, 2015 at 12:54 AM

I will just dump my unoptimized, uncommented customized SmoothFollow script here for your to take some ideas from.

The basic ideas focuses on the camera's frustrum box: You calculate four world points which sit at the camera's field of view's four corners. Then you calculate four more points by taking one frustrum point and going forward (relative to the camera) for a distance equal to the distance between camera and player (his head, preferably). Then I cast rays from each of the four points near the player's position back twards the frustrum points. If one one the points hits an obstacle, I know that one of the camera's viewport corners would clip through terrain, so I move the camera at a distance from the player that is equal to the lowest distance between any of the four rays and their hit.points (or the maximum camera distance, if none have hit anything).

It's a little complicated to describe, but it's much better than casting a signel ray because with one ray, you will have the clipping at corners isue where your camera sees through terrain that is very near. The downside is that thing objects like street lamps are not registered by the rays because the object lies between them, So you could theoretically enhance the method by casting more rays (one through the middle, for example).

 /*
 This camera smoothes out rotation around the y-axis and height.
 Horizontal Distance to the target is always fixed.
 
 There are many different ways to smooth the rotation but doing it this way gives you a lot of control over how the camera behaves.
 
 For every of those smoothed values we calculate the wanted value and the current value.
 Then we smooth it using the Lerp function.
 Then we apply the smoothed values to the transform's position.
 */
 
 
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class SmoothFollow : MonoBehaviour {
 
     // The target we are following
     public Transform target;
     //the position the player looks at (like, on a wall some distance away, or on the ground next to him)
     public Vector3 lookAtTarget;
     public float defaultMinDistance = 0.5f;
     public float defaultMaxDistance = 5f;
     public float defaultMaxHeight = 3f;
     // The distance in the x-z plane to the target
     public float distance = 6.0f;
     public float minDistance = 1.0f;
     public float maxDistance = 6.0f;
     // the height we want the camera to be above the target
     public float maxHeight = 3.0f;
     public float height = 3.0f;
 
     public float dampingFactor = 3.0f;
     public bool collision = false;
     public LayerMask mask;
     private float maximumY;
     private ValueWrapper<float> camAnchorRotX = new ValueWrapper<float>(0f);
     public float horizontalOffsetDefault = 0.22f;
     public float horizontalOffset;
     public bool damping = false;
 
 
     void Start() {
         //CreateFrustrumBox();
         maximumY = Manager.player.GetComponent<PlayerControl>().maximumY;
     }
         
     void Update() {
         camAnchorRotX.Value = target.localEulerAngles.x;
         if(camAnchorRotX.Value > 180) {
             camAnchorRotX.Value -= 360;
         }
         CastFrustrumRays();
     }
 
     void FixedUpdate () {
         // Early out if we don't have a target
         if (target == null) {
             return;
         }
 
         /*
         // Calculate the current rotation angles
         float wantedRotationAngle = target.eulerAngles.y;
         float wantedHeight = target.position.y + maxHeight;
         
         float currentRotationAngle = transform.eulerAngles.y;
         float currentHeight = transform.position.y;
         
         // Damp the rotation around the y-axis
         currentRotationAngle = Mathf.LerpAngle (currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
         
         // Damp the height
         currentHeight = Mathf.Lerp (currentHeight, wantedHeight, heightDamping * Time.deltaTime);
         
         // Convert the angle into a rotation
         Quaternion currentRotation = Quaternion.Euler (0, currentRotationAngle, 0);
         
         // Set the position of the camera on the x-z plane to:
         // distance meters behind the target
         transform.position = target.position;
         transform.position -= currentRotation * Vector3.forward * distance;
         
         // Set the height of the camera
         transform.position = new Vector3(transform.position.x, currentHeight, transform.position.z);
         
         // Always look at the target
         lookAtTarget = new Vector3(target.transform.position.x, target.transform.position.y + maxHeight, target.transform.position.z);
         transform.LookAt (lookAtTarget);
         */
 
 
         //height = maxHeight * (1 - (Mathf.Abs(camAnchorRotX.Value) / maximumY));
         lookAtTarget = target.position + Vector3.up * height + target.right * horizontalOffset;
         Vector3 wantedPosition = lookAtTarget - target.forward * distance;
         if(damping == true) {
             transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * dampingFactor);
         }
         else {
             transform.position = wantedPosition;
         }
 
         // Always look at the target
         transform.LookAt (lookAtTarget);
 
     }
 
     void CreateFrustrumBox() {
 
         float h = Mathf.Tan(GetComponent<Camera>().fov * Mathf.Deg2Rad * 0.5f) * GetComponent<Camera>().nearClipPlane * 2f;
         GetComponent<Collider>().transform.localScale = new Vector3(h * GetComponent<Camera>().aspect, h, 0.01f);
         GetComponent<BoxCollider>().center = new Vector3(0, 0, 100);
     }
 
     void CastFrustrumRays() {
 
         float distanceToCamera = Vector3.Distance(lookAtTarget, transform.position);
 
         Vector3 pos00_Cam = GetComponent<Camera>().ViewportToWorldPoint(new Vector3(0, 0, GetComponent<Camera>().nearClipPlane));
         Vector3 pos01_Cam = GetComponent<Camera>().ViewportToWorldPoint(new Vector3(0, 1, GetComponent<Camera>().nearClipPlane));
         Vector3 pos11_Cam = GetComponent<Camera>().ViewportToWorldPoint(new Vector3(1, 1, GetComponent<Camera>().nearClipPlane));
         Vector3 pos10_Cam = GetComponent<Camera>().ViewportToWorldPoint(new Vector3(1, 0, GetComponent<Camera>().nearClipPlane));
 
         //float forwardOffset = maxDistance - camera.nearClipPlane - (maxHeight - maxHeight * (1 - (Mathf.Abs(camAnchorRotX.Value) / maximumY)));
         float forwardOffset = Mathf.Clamp(distanceToCamera, minDistance, maxDistance);
 
         if(forwardOffset <= 0) {
             forwardOffset = 0.1f;
         }
 
         Vector3 pos00_Target = pos00_Cam + transform.forward * forwardOffset;
         Vector3 pos01_Target = pos01_Cam + transform.forward * forwardOffset;
         Vector3 pos11_Target = pos11_Cam + transform.forward * forwardOffset;
         Vector3 pos10_Target = pos10_Cam + transform.forward * forwardOffset;
 
         Ray ray00 = new Ray(pos00_Target, -transform.forward);
         Ray ray01 = new Ray(pos01_Target, -transform.forward);
         Ray ray11 = new Ray(pos11_Target, -transform.forward);
         Ray ray10 = new Ray(pos10_Target, -transform.forward);
 
         RaycastHit hit00 = new RaycastHit();
         RaycastHit hit01 = new RaycastHit();
         RaycastHit hit11 = new RaycastHit();
         RaycastHit hit10 = new RaycastHit();
 
         Debug.DrawLine(pos00_Target, pos01_Target);
         Debug.DrawLine(pos01_Target, pos11_Target);
         Debug.DrawLine(pos11_Target, pos10_Target);
         Debug.DrawLine(pos10_Target, pos00_Target);
 
         Ray[] rays = new Ray[] {ray00, ray01, ray11, ray10};
         RaycastHit[] hits = new RaycastHit[] {hit00, hit01, hit11, hit10};
         Vector3[] positions_Target = new Vector3[] {pos00_Target, pos01_Target, pos11_Target, pos10_Target};
         Vector3[] positions_Cam = new Vector3[] {pos00_Cam, pos01_Cam, pos11_Cam, pos10_Cam};
 
         int i = 0;
 
         if(Physics.Raycast(ray00, out hit00, maxDistance, mask)) {
             collision = true;
             Debug.DrawRay(pos00_Target, pos00_Cam - pos00_Target, Color.red);
         }
         else if(Physics.Raycast(ray01, out hit01, maxDistance, mask)) {
             collision = true;
             Debug.DrawRay(pos01_Target, pos01_Cam - pos01_Target, Color.red);
         }
         else if(Physics.Raycast(ray11, out hit11, maxDistance, mask)) {
             collision = true;
             Debug.DrawRay(pos11_Target, pos11_Cam - pos11_Target, Color.red);
         }
         else if(Physics.Raycast(ray10, out hit10, maxDistance, mask)) {
             collision = true;
             Debug.DrawRay(pos10_Target, pos10_Cam - pos10_Target, Color.red);
         }
         else {
             collision = false;
         }
 
         if(collision == false) {
             for(i = 0; i < 4; i++) {
                 Debug.DrawRay(positions_Target[i], positions_Cam[i] - positions_Target[i], Color.green);
             }
         }
 
         float minCollisionDistance = maxDistance;
 
         if(collision == true) {
             float distance00 = Vector3.Distance(lookAtTarget, hit00.point);
             float distance01 = Vector3.Distance(lookAtTarget, hit01.point);
             float distance11 = Vector3.Distance(lookAtTarget, hit11.point);
             float distance10 = Vector3.Distance(lookAtTarget, hit10.point);
             minCollisionDistance = Mathf.Min(distance00, distance01, distance11, distance10);
             minCollisionDistance = Mathf.Clamp(minCollisionDistance, minDistance, maxDistance);
         }
         else {
             minCollisionDistance = maxDistance;
         }
 
         distance = minCollisionDistance - Mathf.Abs(0 + horizontalOffset) * 2;
     }
 }
 
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

Camera Collision Not Working 0 Answers

Camera collision 2 Answers

Camera bounce/collision 1 Answer

Accurate Pinch Zoom 1 Answer

why camera does not recognize the collision? 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