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 Kaze_Senshi · Mar 13, 2015 at 08:51 PM · c#camera3d

Dark Souls like camera going through walls, please help

Hello guys, I am working on third person camera like the one in Dark Souls, which orbits around the player adapting its distance to avoid hiding the player.

I found this post about a similar question but there were no suitable answers. We are casting four rays from the camera's position to each border of its near clipping plane. If any of these rays hit a wall, our script corrects the camera's position.

Easier said than done, the camera is behaving quite erratically. Can anyone here help me to understand whats going on or have a better suggestion to solve this problem? The script is right below.

The camera is "erratically" because it works pretty good sometimes and it fails in certain cases. For example, when the player is close of a wall we can move the camera around the player without letting it going through the wall directly. Instead of that the camera is moved like we show in the next picture (orbiting the player until find the obstacle, them moving touching the wall, passing through the player and starting the cycle again), however when getting close of the player it starts to move a bit weirdly and sometimes it goes a bit inside the wall (the objective of the raycasting was to avoiding this kind of behavior).

alt text

Thanks in advance.

Our most recent (and problematic) camera script:

 using UnityEngine;
 using System.Collections;
  
 public class MonkeyCamera : MonoBehaviour
 {
     public Transform Target;
     public float Distance = 5.0f;
     public float xSpeed = 250.0f;
     public float ySpeed = 120.0f;
     public float yMinLimit = -20.0f;
     public float yMaxLimit = 80.0f;
     public float freeSpeed = 3;
     public float invisibleWallPrevent = 0.7f;
     public float charClippingPrevent = 2.0f;
 
     private Rigidbody targetRigidBody;
     private string headstr = "Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 Spine1/Bip001Neck/Bip001 Head";
     private float x;
     private float y;
     private Transform head;
     private Camera camera;
     private float fovx;
     private float fovy;
    
     void Awake()
     {
         Vector3 angles = transform.eulerAngles;
         x = angles.x;
         y = angles.y;
        
         targetRigidBody = (Rigidbody)Target.GetComponent("Rigidbody");
         head = Target.transform.FindChild(headstr);
         camera = transform.camera;
         fovy = camera.fieldOfView;
         fovx = Mathf.Rad2Deg * (   2 * Mathf.Atan(  Mathf.Tan( (fovy * Mathf.Deg2Rad) / 2 )
                                                      * camera.aspect
                                                  )
                                );
     }
    
     void LateUpdate()
     {
         if(Target != null)
         {
             Quaternion rotation;
             if( Input.GetKeyDown(KeyCode.E) )
             {
                 //centralizar camera
                 y = Target.transform.eulerAngles.y;
                 //rotation = Quaternion.Euler(0, desiredAngle, 0);
                 x = Target.transform.eulerAngles.x;
             }
             else
             {
                 x += (float)(Input.GetAxis("Mouse X") * xSpeed);
                 y -= (float)(Input.GetAxis("Mouse Y") * ySpeed);
             }
             y = ClampAngle(y, yMinLimit, yMaxLimit);
             rotation = Quaternion.Euler(y, x, 0);
 
            
             Vector3 position = rotation * (new Vector3(0.0f, 0.0f, -Distance)) + head.position;
 
             transform.rotation = rotation;
             transform.position = position;
 
 
 
             Vector3 rayDirection = Vector3.Normalize(transform.position - head.position);
             RaycastHit[] hits = Physics.RaycastAll(head.position, rayDirection, Distance);
             float minDist = Distance;
             Vector3 hitPoint = new Vector3();
             for(int i = 0; i < hits.Length; i++)
             {
                 if( !hits[i].transform.Equals(Target.transform) && hits[i].distance < minDist )
                 {
                     minDist = hits[i].distance;
                     hitPoint = hits[i].point;
                 }
 
             }
             if(minDist < Distance)
             {
                 Vector3 d = (hitPoint - head.transform.position)
                             * ( 1 + (camera.nearClipPlane / minDist) );
                 transform.position = head.transform.position + d;
             }
 
             Vector3 ncp = Vector3.Normalize(transform.forward) * camera.nearClipPlane;
             float semiw = Vector3.Magnitude(ncp) * Mathf.Tan(fovx * Mathf.Deg2Rad / 2);
             float semih = Vector3.Magnitude(ncp) * Mathf.Tan(fovy * Mathf.Deg2Rad / 2);
 
             Vector3 rv = Vector3.Normalize(transform.right) * semiw + ncp;
             Vector3 lv = Vector3.Normalize(-1 * transform.right) * semiw + ncp;
             Vector3 uv = Vector3.Normalize(transform.up) * semih + ncp;
             Vector3 dv = Vector3.Normalize(-1 * transform.up) * semih + ncp;
 
             wallClipAjust(rv);
             wallClipAjust(lv);
             wallClipAjust(uv);
             wallClipAjust(dv);
 
             transform.LookAt(head.position);
 
             Debug.DrawLine(transform.position, transform.position + rv);
             Debug.DrawLine(transform.position, transform.position + lv);
             Debug.DrawLine(transform.position, transform.position + dv);
             Debug.DrawLine(transform.position, transform.position + uv);
 
         }
     }
 
     private void wallClipAjust(Vector3 vector)
     {
         RaycastHit[] hits = Physics.RaycastAll( transform.position - vector, Vector3.Normalize(vector), Vector3.Magnitude(vector * 2) );
         //assumindo que o maximo de hits para o near clip plane eh 1
         if(hits.Length != 0)
         {
             //Vector3 d = ((2 * Vector3.Magnitude(vector)) - hits[0].distance) * Vector3.Normalize(hits[0].normal);
             float d = (Vector3.Magnitude(vector * 2) - hits[0].distance)
                       * Mathf.Cos(Vector3.Angle( (-1 * hits[0].normal),
                                                    vector
                                                  )
                                    );
             transform.position += d * Vector3.Normalize(hits[0].normal);
         }
     }
    
     private float ClampAngle(float angle, float min, float max)
     {
         if(angle < -360)
         {
             angle += 360;
         }
         if(angle > 360)
         {
             angle -= 360;
         }
         return Mathf.Clamp (angle, min, max);
     }
 }


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 Cherno · Mar 13, 2015 at 09:48 PM 0
Share

"The camera bevaves quite eratically" is not a very precise description of the issue. What exactly is the problem with the camera's behavior?

avatar image Kaze_Senshi · Mar 13, 2015 at 10:08 PM 0
Share

Sorry, I added more details about its behavior to try to show the problem in a better way.

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.

Follow this Question

Answers Answers and Comments

21 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

Related Questions

Limiting vertical camera rotation 0 Answers

Why is the camera going crazy when the player moves? 0 Answers

Change from 3D to 2D 1 Answer

3D camera smooth rotation and mouse wheel zoom 2 Answers

3D Isometric Camera C# - Center on player? 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