Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Issues with raycasting/linecasting and moving camera in front of walls

Discussion in 'Scripting' started by Foestar, Oct 6, 2018.

  1. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    So I'm having trouble with adjusting my camera distance when hitting or hiding behind walls. The logic for this didn't seem to crazy in my head when I started, but at this point I keep having one issue or another and am wondering what I'm doing wrong.

    My first thought was very simple, as I had done this long long ago in a previous project. I however no long have that project to reference off, but hey, how hard could it be right? So I started with a raycast. Not I realize that when doing a raycast for this I'm trying to see if there's anything between the player and the camera. Wording is key, meaning I would have to start from the player and send the ray towards the camera's current position. No biggy. Or at least I thought so. I've noticed that I get some seriously odd hits when sending a raycast out from said player to camera. Here is my code, I'll break down the ending section that I was trying after.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class cameraControls : MonoBehaviour {
    4.  
    5.     //player model that we gravitate around
    6.     [SerializeField]
    7.     private Transform Player;
    8.  
    9.     //the left/right or X direction the camera is facing
    10.     private float heading = 0;
    11.  
    12.     //the up/down or Y direction the camera is facing
    13.     private float tilt = 20;
    14.  
    15.     //the distance the camera will hover at
    16.     private float camDist = 10;
    17.  
    18.     //not the player's model actual height, but the cameras height aka the player
    19.     private float playerHeight = 2;
    20.  
    21.     void Update ()
    22.     {
    23.  
    24.     }
    25.  
    26.     void LateUpdate ()
    27.     {
    28.         //get our X heading
    29.         heading += Input.GetAxis("Mouse X") * Time.deltaTime * 180;
    30.  
    31.         //get our Y tilt
    32.         tilt += Input.GetAxis("Mouse Y") * Time.deltaTime * -180;
    33.  
    34.         //clamping the tilt so the player's camera doesn't go too far on Y rotation
    35.         tilt = Mathf.Clamp(tilt, -45, 45);
    36.  
    37.         //set the rotation of the camera
    38.         transform.rotation = Quaternion.Euler(tilt, heading, 0);
    39.  
    40.         //set the position of the camera
    41.         transform.position = Player.position - transform.forward * camDist + Vector3.up * playerHeight;
    42.  
    43.         //do our camera check to make sure nothings between the player and the camera
    44.         //adjust the camera if there is something blocking the view
    45.         DoCameraCheck();
    46.     }
    47.  
    48.     //Camera check to make sure nothing's between the camera and us
    49.     void DoCameraCheck()
    50.     {
    51.         RaycastHit objectHit;
    52.  
    53.         //our hard to make raycast
    54.         if(Physics.Raycast(Player.position, transform.position, out objectHit))
    55.         {
    56.             camDist = objectHit.distance;
    57.  
    58.             //camDist = Mathf.Clamp(camDist, 4, 10);
    59.         }
    60.         else
    61.         {
    62.             camDist = 10;
    63.         }
    64.         Debug.DrawRay(Player.position, transform.position, Color.yellow);
    65.     }
    66. }
    67.  
    So what I did was create the raycast and a hit, if the ray hit anything it would adjust the camDist to that distance. I even played with clamping to ensure it didn't go over or under a certain amount. And if it's not hitting anything, reset back to default 10. The problem is as I kept playing around with this it worked decent on the wall, but was hitting nothing above, crazy on the floor with a flickering effect, and placement seemed off. I even switched between linecast and raycast and honestly had better luck with that.

    I then tried drawing a ray between the 2 and it looks fine in that case until I started trying to move things. Long story short, I've gained no ground the last few days and have only obtained headaches trying to do what I thought would be a simple concept.
     
  2. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    So also just noticed that if I remove most of the code and just add a ray from object to object it works fine until I move. So it's gotta be an issue with placement being thrown off on movement.

    Code (CSharp):
    1. //Camera check to make sure nothing's between the camera and us
    2.     void DoCameraCheck()
    3.     {
    4.         Debug.DrawRay(Player.position, transform.position, Color.yellow);
    5.     }
     
  3. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    So I've done some none stop efforts to figure out this problem and I'm starting to think it's either a bug (less likely as many more would have the same issue and be posting about it) or I just don't know what I'm doing with raycasts.

    When creating a drawn ray between two moving objects I'm finding the second object drawn to doesn't update the drawn ray when moved. For example, the basic code above this post shows a code when attached to your camera will draw a ray from the player to the camera itself in yellow format. When the camera is moved in the inspector or scene window the ray updates or rather moves with it continuing to draw between the two. But when the player is moved the ray doesn't draw to the camera, but rather where the camera was relative to the player. Meaning if I were to move the player 5 on the X axis, the ray would draw 5 away from the actual camera on the X axis as well because it thinks it was moved with the player.

    I'm not understanding why it's doing this behaviour and was wondering if anyone else could enlighten me. I have a quick video demonstrating this below.
     
  4. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
    drawray needs startpos and direction, you are giving startpos and endpos..?
    maybe you wanted to use DrawLine() ?
     
  5. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    Yeah I was using drawline before but someone told me to use raycast because drawline couldn't do distances. Which I think is wrong because it was working distance wise for me, but had odd hits at times.

    So you have to have a direction for a raycast and can't simply do a draw from point to point? It seems to be half working and I feel like it's something obvious but out of reach.
     
  6. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
    oh i see, your raycast also does that,
    in LineCast you can do startpos, endpos, but raycast needs startpos, direction.
     
  7. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    So I just tried doing a direction test instead of from point to point and it ends up with similar results of the raycast being drawn to the wrong relative spot when the player's moved. Same error results.
     
  8. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
    can you show the code for raycast and drawray?
     
  9. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    So right off just a basic code from one object to another. If you place this in a C# file as is, place it on the camera and drag another object to draw to into the transform it will work drawing a line between the two.

    Code (CSharp):
    1. [SerializeField]
    2.     private Transform Player;
    3.  
    4. void Update()
    5.     {
    6.         Debug.DrawRay(Player.position, transform.position, Color.yellow);
    7.     }
    The second option is getting a direction like you stated but it yields the same results.

    Code (CSharp):
    1. [SerializeField]
    2.     private Transform Player;
    3.  
    4. void Update()
    5.     {
    6.         Vector3 raycastDir = transform.position - Player.transform.position;
    7.         Debug.DrawRay(Player.position, raycastDir, Color.yellow);
    8.     }
    Edit, had to change to ray, I put linecast instead of rays.
     
    Last edited: Oct 8, 2018
  10. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
    you need to calculate direction inside Update too, if it isnt
     
    Foestar likes this.
  11. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    Oops, yeah that was meant to be in Update as well. Fixed, but still holds same results.
     
  12. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    Wait a minute. Now it's working. Lmao, hold up one sec. I'm gonna laugh if this whole time I've been fighting this I didn't have my original code in the Update.
     
  13. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    Okay, so I feel kinda dumb now. Haha, made to look bad by an 8 bit cheeseburger. :D:D:D:D

    Thanks man, sometimes it just takes another pair of eyes for this stuff.