Search Unity

Linrenderer not working as expected. Not following player movment accuratly.

Discussion in 'Scripting' started by InfinitePath, Feb 20, 2021.

  1. InfinitePath

    InfinitePath

    Joined:
    Apr 2, 2016
    Posts:
    9
    Hello there!,

    I'm currently working in a game where there are some blocks that fall and the player needs to destruct them. The player just can shoot straight in the Y axis so he/she would need to place the player under the falling block and shoot to not let them get the ground. So I create this aiming system to help the player understand if it's right below the targeted block. I create a ray that is used to render a line from the end of the weapon that hit what is in it's way. The linerenderer is atached to an object witch is at the end of the weapon.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class AimRenderer : MonoBehaviour
    7. {
    8.     #region Dependencies
    9.     public LayerMask noBlockingLayers;
    10.     public Transform origin;
    11.     public Transform source; //This is the top grid witch spawn the blocks.
    12.     #endregion
    13.     #region Private Variables
    14.     private LineRenderer lineRenderer;
    15.     #endregion
    16.     // Start is called before the first frame update
    17.     void Awake()
    18.     {
    19.         lineRenderer = origin.gameObject.GetComponent<LineRenderer>();
    20.     }
    21.  
    22.     // Update is called once per frame
    23.     void Update()
    24.     {
    25.         //We detect if there is somthing above the player
    26.         float yEndPos = DetectDestructables();
    27.         Debug.Log("Aim target pos: " + new Vector3(transform.position.x, yEndPos, transform.position.z));
    28.         //We render a line up.
    29.         DrawAimingLine(origin.position, new Vector3(transform.position.x, yEndPos, transform.position.z));
    30.  
    31.     }
    32.  
    33.     /// <summary>
    34.     /// Detects if there is an object above the player.
    35.     /// </summary>
    36.     /// <returns>float: Y position of the blocking objects</returns>
    37.     private float DetectDestructables()
    38.     {
    39.         RaycastHit hitInfo;
    40.  
    41.         if (Physics.Raycast(origin.position, origin.up, out hitInfo, noBlockingLayers))
    42.         {
    43.             Debug.Log(hitInfo.collider.name + " is in aim.");
    44.              
    45.             return hitInfo.collider.transform.position.y;
    46.         }
    47.         else
    48.         {
    49.             Debug.Log( "No block is in aim.");
    50.             return source.position.y;
    51.         }
    52.     }
    53.     /// <summary>
    54.     /// Draws a line from the origin point to the end point.
    55.     /// </summary>
    56.     /// <param name="originPos">Vector3: position where the line begins</param>
    57.     /// <param name="endPos">Vector3: position where the line ends</param>
    58.     private void DrawAimingLine(Vector3 originPos, Vector3 endPos)
    59.     {
    60.         Vector3[] positions = { originPos, endPos };
    61.  
    62.         lineRenderer.startWidth = 0.2f;
    63.         lineRenderer.endWidth = 0.2f;
    64.  
    65.         lineRenderer.SetPositions(positions);
    66.     }
    67. }
    68.  
    69.  

    My issue comes when the player moves, and the line rendered stays in the place for few moments before its rendered again. So, this happens to create a feeling of lag which is annoying. The function that draws the line is being rendered every frame in the update method so I dont understand why this delay is happening.

    All this for saying, that would be very much appreciated If there is any clue, hint, or workaround to solve this issue.

    Thanks for reading until here :)
    Be Happy
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Is it maybe because either
    origin
    is moving and
    transform
    is not?

    I ask because I see line 29 using both of those position sources. You already have a Debug.Log() online 27, might as well also print what
    origin.position
    is too!
     
  3. InfinitePath

    InfinitePath

    Joined:
    Apr 2, 2016
    Posts:
    9
    Thanks for your answer!.

    Both are part of the same object, so both are moving the same amount. First I tried setting the origin position -witch is the end from where the line should be rendered- then I tried to change it to the transform of the player object, but the result is the same.

    The hierarchy is as follow:
    - Player (AimRenderer)
    -- Tube
    ---End (LineRenderer) Should this component be in the player object?
     
    Last edited: Feb 20, 2021
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Well only thing is to go into line 61 and print out the two points, see why they are different, then back up to all the places that call in. Something isn't doing this:

     
  5. InfinitePath

    InfinitePath

    Joined:
    Apr 2, 2016
    Posts:
    9
    When I print the transform position and the start and end point of the render they are in the same x and z coordinates :S. So this makes me confused. When is when the linerenderer mismatch with the player movement?.

    Transform pos: (-3.0, 0.5, 0.0)=>LR start pos: (-3.0, 1.5, 0.0) LR end pos:(-3.0, 18.0, 0.0)
    UnityEngine.Debug:Log(Object)
    AimRenderer:DrawAimingLine(Vector3, Vector3) (at Assets/Scripts/Player/AimRenderer.cs:61)
    AimRenderer:Update() (at Assets/Scripts/Player/AimRenderer.cs:28)

    This is a graphical image of what is happening. Sorry about graphics is just a prototype, I've been woking few days on.

     
  6. InfinitePath

    InfinitePath

    Joined:
    Apr 2, 2016
    Posts:
    9
    I got it!! :D

    I've moved the rendering of the line to LateUpdate and now it works like a charm. Render process is made in LateUpdate when all physics are already calculated. So I guess that the rendering of the linerenderer was missing some frames because of that. The render of the ray was calculated sometimes before physics, so this provoked that the ray was rendered in some frames in the same poition and not updating it's position. The line was moving after being rendered. See Order of execution for event functions



    Thanks for your help, last comment gave me the idea!. Hope this could be usefull for some others.
    Cheers!
     
    Last edited: Feb 21, 2021
    Kurt-Dekker likes this.
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Awesome!!!

    This is an excellent reference to always keep around.

    If you can't use LateUpdate, another way is to remove
    void Update()
    and instead make yourself a
    public void MyUpdate()
    that you explicitly call from your player mover, AFTER you move... that lets you have very explicit control of timing.
     
    InfinitePath likes this.
  8. InfinitePath

    InfinitePath

    Joined:
    Apr 2, 2016
    Posts:
    9
    Yes, I haven't thought about it. But this is also a very good approach.
     
    Kurt-Dekker likes this.