Search Unity

Drawing a ray as a Cylinder between two moving objects

Discussion in 'Scripting' started by VSZM, Oct 31, 2014.

  1. VSZM

    VSZM

    Joined:
    Nov 18, 2013
    Posts:
    8
    Hi!

    I am new to Unity and I am stuck with an error for days now.

    What I want to do is to have two objects in my scene, which the user can move with touch input. I have this part working.

    I also want to have a ray of laser between these two objects. For now I am modelling the laser as a Cylinder. The starting point is one of the objects, and I shoot a ray towards the other object and have the Cylinder to be raycasthit.distance tall.

    This also works almost fine. The problem is that when I move the object that is receiving the raycast the ray does not hit it even though the ray emitter object is set to LookAt the receiver.

    I have defined script execution order in a way, that this should work.

    1. Move objects if they are touched.
    2. Make the receiver object lookAt the emitter.
    3. Make the emitter object lookAt the receiver.
    4. Cast the ray and draw the laser cylinder accordingly.

    I have ran out of ideas.

    Can anyone please look at my project and tell me what is wrong?
     

    Attached Files:

  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    You can do this without the need for rays at all (assuming there's never anything blocking the line between the two points), so you can just change the 4th step like so:
    Code (CSharp):
    1. Vector3 pointA ... //one of the points
    2. Vector3 pointB ... //the other point
    3. float distanceBetween = (PointB - PointA).magnitude;
    4. //Then set cylinder size to that distance
     
  3. VSZM

    VSZM

    Joined:
    Nov 18, 2013
    Posts:
    8
    Hi hpjohn, thank you for your input!

    Yes I was thinking about falling back to this solution, but your assumption does not hold. I would like to have objects being able to interfere with the laser. This is why I need the raycast.

    If no one can provide me with a solution to this problem, I will fall back, but this costs me cutting off features I wanted to have.
     
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    So why is the ray from point A not reaching point B? you have a way to get the needed distance and direction to cast
     
  5. VSZM

    VSZM

    Joined:
    Nov 18, 2013
    Posts:
    8
    Have you checked the attached project in the first post? It does reach when they don't move, or move slowly. But if I move them a little bit faster, than it does not hit for a few frames.
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    I'm going to say now, I didn't look at your files. I don't really want to be downloading and opening your project.



    You mention script execution order. This leads me to believe that you think if one script moves an object, then another script does a ray cast, and that other script is later in the execution chain, that it'll pick up that move.

    It won't.

    In unity, if you move a GameObject with a collider on it, physics isn't updated until the next physics update. I've played around with it and noticed that it'll often pick up if you moved it out of the way (a raycast will not find anything if you move something out of the way before raycasting). But it won't pickup anything if you moved into the path.

    You can see this in this code:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class OverloadTest : MonoBehaviour
    6. {
    7.  
    8.     void Start()
    9.     {
    10.  
    11.         this.StartCoroutine(Foo());
    12.     }
    13.  
    14.     IEnumerator Foo()
    15.     {
    16.         var go = new GameObject("Target");
    17.         var coll = go.AddComponent<BoxCollider>();
    18.         go.transform.position = new Vector3(3f, 0f, 0f);
    19.  
    20.  
    21.  
    22.         yield return new WaitForSeconds(1.0f);
    23.  
    24.         Ray ray = new Ray(Vector3.zero, new Vector3(1f, 0f, 0f));
    25.         RaycastHit hit;
    26.  
    27.         if(Physics.Raycast(ray, out hit, 100f))
    28.         {
    29.             Debug.Log("1) Hit: " + hit.collider.name);
    30.         }
    31.         else
    32.         {
    33.             Debug.Log("1) FAILED!");
    34.         }
    35.  
    36.         yield return new WaitForSeconds(1.0f);
    37.  
    38.         var p = coll.transform.position;
    39.         p.y = 10f;
    40.         coll.transform.position = p;
    41.         if(Physics.Raycast(ray, out hit, 100f))
    42.         {
    43.             Debug.Log("2) Weird, one would think you'd miss: " + hit.collider.name);
    44.         }
    45.         else
    46.         {
    47.             Debug.Log("2) Worked as expected. We didn't hit the cube that was moved.");
    48.         }
    49.  
    50.         yield return new WaitForSeconds(1.0f);
    51.  
    52.         p = coll.transform.position;
    53.         p.y = 0f;
    54.         coll.transform.position = p;
    55.         if (Physics.Raycast(ray, out hit, 100f))
    56.         {
    57.             Debug.Log("3) Worked as expected. We hit the cube: " + hit.collider.name);
    58.         }
    59.         else
    60.         {
    61.             Debug.Log("3) Weird, one would think we would hit the cube after moving back in place.");
    62.         }
    63.  
    64.         yield return new WaitForFixedUpdate();
    65.  
    66.         if (Physics.Raycast(ray, out hit, 100f))
    67.         {
    68.             Debug.Log("4) Worked after waiting for FixedUpdate: " + hit.collider.name);
    69.         }
    70.         else
    71.         {
    72.             Debug.Log("4) Weird...");
    73.         }
    74.  
    75.  
    76.  
    77.         GameObject.Destroy(coll.gameObject);
    78.  
    79.     }
    80.  
    81.  
    82. }
    83.  
    84.  
    Place on a GameObject in an otherwise empty scene and press play.


    You'll get the readout:

     
  7. VSZM

    VSZM

    Joined:
    Nov 18, 2013
    Posts:
    8
    Hi lordofduct! Thank you for your response, this was the problem indeed. Now I do all the input handling in an Update section, and start a Corutine which waits for a FixedUpdate before the raycast. This solved the problem, thank you.

    If you want to earn some Unity Answer reputation, post your answer here: http://answers.unity3d.com/questions/818838/drawing-a-ray-as-a-cylinder-between-two-moving-obj.html