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 /
avatar image
0
Question by dragonking300 · Mar 14, 2017 at 12:12 AM · c#scripting beginnercamera-movement

How do I make my camera not clip through walls?

I don't want my camera script to rotate or do anything special because I have that handled all ready. All I want is my camera's position to scale depending on how close it is to the wall.

How I want my camera script to work in 2 ways:

  1. I want my Camera to change its position based on what surface it collided with(I have this accomplished)

  2. I want my camera to scale its position based on how closely it is to the wall(Main problem).

My scene:

alt text

My script(the bit with /* is my attempt at the problem)

    using UnityEngine;
    using System.Collections;
     
     public class CameraScript : MonoBehaviour
     {
     
         public int count;
         private Vector3 Campos;
         public Transform player;
         public GameObject Player;
         public int RayDistance = 10;
         [HideInInspector]
         public GameObject Wall;
     
         public void Start()
         {
          //   if (Campos == null)
            // {
                 Campos = new Vector3(0f, 5f, -15f);
            // }
         }
     
         void FixedUpdate()
         {
             //if (connection)
             
                 transform.position = Player.transform.position + Campos;
                 transform.LookAt(player);
             
     
         }
         public void Update()
         {
             /*RaycastHit hit;
             Ray LandingRay = new Ray(transform.position, Vector3.back);
     
     
             if (Physics.Raycast(LandingRay, out hit, RayDistance))
             {
                
                 Wall = hit.collider.gameObject;
                 float dist = Vector3.Distance(hit.point, transform.position);
                 Debug.Log("distance = " + dist);
                 if (dist <= 2)
                 {
                     //Camera math stuff
                     //Btw tell me step by step how it works so Ik how to make a script like this in the future
                 } 
             }
             */
             if (count == 0)
             {
     
     
                 Campos = new Vector3(0f, 5f, -15f);
                // Debug.Log(count);
                 Player.transform.eulerAngles = new Vector3(0f, 0f, 0f);
     
             }
             else
             {
                 if (count == 1)
                 {
     
     
                     Campos = new Vector3(15f, 5f, 0f);
                    // Debug.Log(count);
                     Player.transform.eulerAngles = new Vector3(0f, 270f, 0f);
     
                 }
                 else
                 {
                     if (count == 2)
                     {
     
     
                         Campos = new Vector3(0f, 5f, 7f);
                         //Debug.Log(count);
                         Player.transform.eulerAngles = new Vector3(0f, 180f, 0f);
     
                     }
                     else
                     {
                         if (count == 3)
                         {
     
                             Campos = new Vector3(0f, 8f, 15);
                             //Debug.Log(count);
                             Player.transform.eulerAngles = new Vector3(0f, 90f, 0f);
     
                         }
                         else
                         {
                             if (count <= -1)
                             {
                                 count = 3;
                             }
                             else
                             {
                                 if (count <= 4)
                                 {
                                     count = 0;
                                 }
                                 //the script is going to account for the ceiling position and floor position so don't worry about that
                             }
                         }
                     }
                 }
             }
         }
     }

So, I just want a improvised version of my current script but I want it to scale its position based on how close it is to the wall. I've been trying this for a week so I am clueless on how to do this by my self...

Edit: Here is the script I forgot to mention that effects camera(sorry >_< )

 using UnityEngine;
 using System.Collections;
 
 public class Dash : MonoBehaviour {
 
     public GameObject Previouscollided;
     private GameObject collided;
     public LayerMask Wall;
     Vector3 newPosition;
 
     public GameObject Wall1;
     public GameObject Wall2;
     public GameObject Wall3;
     public GameObject Wall4;
     public GameObject Floor;
     public GameObject Ceiling;
     public GameObject RecentWall;
     public int speed;
 
 
     void Start ()
     {
         newPosition = transform.position;
     }
     
     // Update is called once per frame
     void Update ()
     {
         if (Input.GetMouseButtonDown(0))
         {
             RaycastHit hit;
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                 if(Physics.Raycast(ray, out hit, Wall.value))
             {               
                 collided = hit.collider.gameObject;
                 RecentWall = collided;
                 //Debug.Log(collided);
                 Cameraposition();
                 collided.layer = LayerMask.NameToLayer("Ignore Raycast");
                 newPosition = hit.point;                   
                  Previouscollided.layer = LayerMask.NameToLayer("Wall");
                 Previouscollided = hit.collider.gameObject;
                 //Debug.Log(Previouscollided);
             }
         }
 
         if (collided == Wall1)
         {
             transform.position = Vector3.Lerp(transform.position, newPosition + new Vector3(0, 0, -2f), speed * Time.deltaTime);
         }
 
         if (collided == Wall2)
         {
             transform.position = Vector3.Lerp(transform.position, newPosition + new Vector3(0, 0, 2), speed * Time.deltaTime);
         }
 
         if (collided == Wall3)
         {
             transform.position = Vector3.Lerp(transform.position, newPosition + new Vector3(-2, 0, 0), speed * Time.deltaTime);
         }
 
         if (collided == Wall4)
         {
             transform.position = Vector3.Lerp(transform.position, newPosition + new Vector3(2, 0, 0), speed * Time.deltaTime);
         }
 
         if (collided == Floor)
         {
             transform.position = Vector3.Lerp(transform.position, newPosition - new Vector3(0, 0, 0), speed * Time.deltaTime);
         }
 
         if (collided == Ceiling)
         {
             transform.position = Vector3.Lerp(transform.position, newPosition - new Vector3(0, 0, 0), speed * Time.deltaTime);
         }
     }
     public void Cameraposition()
     {
         if(collided == Wall1)
         {
             GameObject theCamera = GameObject.Find("Main Camera");
             CameraScript cameraScript = theCamera.GetComponent<CameraScript>();
             cameraScript.count = 0;
         }
         if (collided == Wall2)
         {
             GameObject theCamera = GameObject.Find("Main Camera");
             CameraScript cameraScript = theCamera.GetComponent<CameraScript>();
             cameraScript.count = 1;
         }
         if (collided == Wall3)
         {
             GameObject theCamera = GameObject.Find("Main Camera");
             CameraScript cameraScript = theCamera.GetComponent<CameraScript>();
             cameraScript.count = 2;
         }
         if (collided == Wall4)
         {
             GameObject theCamera = GameObject.Find("Main Camera");
             CameraScript cameraScript = theCamera.GetComponent<CameraScript>();
             cameraScript.count = 3;
         }
         if (collided == Floor)
         {
             GameObject theCamera = GameObject.Find("Main Camera");
             CameraScript cameraScript = theCamera.GetComponent<CameraScript>();
             cameraScript.count = 4;
         }
         if (collided == Ceiling)
         {
             GameObject theCamera = GameObject.Find("Main Camera");
             CameraScript cameraScript = theCamera.GetComponent<CameraScript>();
             cameraScript.count = 5;
         }
     }
 }

my-stuff.png (254.9 kB)
Comment
Add comment · Show 4
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 ifdef_ben · Mar 15, 2017 at 07:34 PM 0
Share

What do you mean by "I want my camera to scale its position based on how closely it is to the wall." ? What is your expected behavior when the camera gets closer to the wall?

Scaling a position does not make much sense unless you change the camera's parent scale, then it will have impact the camera's position if the local translation is not at (0,0,0).. but I don't think that's what you meant..

avatar image ifdef_ben · Mar 15, 2017 at 07:44 PM 0
Share

Also, what is the purpose of your count variable? Is it used to represent the closest wall? It feels like some of your code is missing, as it's always staying at 0. (Also, using a switch here, would make things much more easy to read). Like this:

 switch(count)
 {
    case 0:
        Campos = new Vector3(0f, 5f, -15f);
        Player.transform.eulerAngles = new Vector3(0f, 0f, 0f);
        break;
    case 1:
        Campos = new Vector3(15f, 5f, 0f);
        Player.transform.eulerAngles = new Vector3(0f, 270f, 0f);
        break;
     case 2:
         //etc..
 }
avatar image dragonking300 ifdef_ben · Mar 15, 2017 at 10:25 PM 0
Share

sorry I took awhile to respond and thank you to being the first person to try to put a meaningful solution and so I will clarify. The Way count works is when I click on one of the walls on the scene the camera switches its position so if I clicked on say Wall1 I will have my camera switch positions so it is facing at the player and away from wall 1 etc etc... Also, for scaling depending how close my camera is to the wall. I mean I want my camera to be closer/farther from the wall depending on how close the player is to the wall but I don't want it to clip because the way the script works currently The camera changes position according to player position but it doesn't account for the wall behind it so it clips through.

I want my camera to work like the script in this tutorial. I tried to follow this tutorial but it has extra functions for orbiting and he adds parts to his script out of video so.(https://www.youtube.com/watch?v=$$anonymous$$kbovxhw$$anonymous$$4I)

avatar image ifdef_ben dragonking300 · Mar 15, 2017 at 10:44 PM 0
Share

Well, you could calculate the first intersecting point behind the camera and then use a ratio (lerp) between that point and the player's position. That way the camera would always stay between the player and the wall behind it and would move away from the wall as the player move away from it.

You'd probably have to cap that lerp distance though, as I'm not sure you would want this behavior when the camera is far from a wall.

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by abdullahsyyd · Mar 14, 2017 at 05:51 AM

@dragonking300 You can improve this by using Physics.Linecast , it can help you to detect anything coming between cube and camera. Linecasting from camera will help you detect any hurdles between target and camera then you can translate your camera position according to detection.

Comment
Add comment · Show 1 · 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 dragonking300 · Mar 14, 2017 at 04:00 PM 0
Share

I have no clue how to do that mathematically + I can't improve my script with extra features if I can't get the core ones to work...

avatar image
0

Answer by ifdef_ben · Mar 15, 2017 at 11:09 PM

If you put colliders on your walls you could do something like this:

 //inside camera class
 Vector3 CalculateCameraPosition(float maxLerpDist = -1f)
 {
    Vector3 result = transform.position;
    //here put a ratio between 0 and 1.
    //0.8 means the camera will be place at 80% of the distance between the player and the wall.
    float ratio = 0.8f; 
    //We start a ray cast originating from the player position, in the direction facing the back of the camera
    Ray ray = new Ray(player.transform.position, -transform.forward);
    RaycastHit rayHit;
    //Looking for the wall behind the camera
    if(Physics.Raycast(ray, out rayHit))
    {
       //We calculate the distance between the player and the intersecting wall behind the camera and get 80% of the distance by multiplying the ratio.
       float distance = (Player.transform.position - rayHit.point).magnitude * ratio;
       //If we do not set a maxLerpDist or if the maxLerpDist is set and superior to the distance.
       if(maxLerpDist < 0 || distance < maxLerpDist)
       {
           //we place the result at 80% of the distance between the player and the wall
           result = Vector3.Lerp(Player.transform.position, rayHit.point, ratio);
       }
    }

    return result;
 }
Comment
Add comment · Show 6 · 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 dragonking300 · Mar 16, 2017 at 12:19 AM 0
Share

Where in my camera script do I put it?

avatar image ifdef_ben dragonking300 · Mar 16, 2017 at 12:32 AM 0
Share

This is a function that returns a position vector, you put it like every other function in your class.. And you call it to get a position between the wall and the player.. That you could then apply to the camera using for instance "Transform.Position = CalculateCameraPosition();"...

avatar image dragonking300 ifdef_ben · Mar 16, 2017 at 03:08 AM 0
Share

What should I do if the camera is outside of the wall tho(I'll be experimenting while I wait)

I tried this but if the camera gets to close to the wall it becomes a first person camera :/

 void FixedUpdate()
 {
  ImprovisedCameraPosition = Vector3.Lerp(PreviousCampos, Campos, speed);
         transform.position = Player.transform.position + ImprovisedCameraPosition;
         transform.LookAt(player);
         transform.position = CalculateCameraPosition(Campos.magnitude);
 }

Show more comments

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

301 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 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

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Camera that follows rotating object with mouse input 0 Answers

How do I make a coroutine from another script stop? 3 Answers

Having Trouble animating camera at start of game 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