Search Unity

Resolved How can I display points in the scene or draw a line between them?

Discussion in 'Scripting' started by Gamadrila, Apr 2, 2022.

  1. Gamadrila

    Gamadrila

    Joined:
    Sep 5, 2021
    Posts:
    142
    Hello everyone.
    5.png
    I started developing the combat system. The picture shows what I’m looking for.
    I use the A* Pathfinding Project library for this.Using this code and LineRenderer..
    Code (CSharp):
    1.  void Update()
    2.         {
    3.             ai2.destination= target.position;
    4.             var buffer = new List<Vector3>();
    5.  
    6.             ai.GetRemainingPath(buffer, out bool stale);
    7.             lin.positionCount = buffer.Count;
    8.             lin.SetPositions(buffer.ToArray());
    9.         }
    I got something like this.
    1.jpg
    This looks bad. Are there other ways to draw a line? For example, through a projector.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Gamadrila likes this.
  3. Gamadrila

    Gamadrila

    Joined:
    Sep 5, 2021
    Posts:
    142
    it's a 2d sprite editor, something like photoshop. I need to draw a line by points in 3d. Linear render builds a line through the terrain. Now I'm trying to figure out how to do it with projectors. Create a projector at each point, then destroy it. But the problem is that the points are unevenly spaced. Are there any other ways?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    The default LineRenderer mostly falls down on mitering and billboarding, so if you give it extra points (or even use multiple separate LineRenderers) you can often get better results.

    You could always look at an Asset Store package such as Vectrosity, which is basically LineRenderer the way it probably should have been in the first place. :)

    Alternately you could generate your own geometry based on exactly what you need. My MakeGeo project has tons of little examples of producing geometry in Unity.

    MakeGeo is presently hosted at these locations:

    https://bitbucket.org/kurtdekker/makegeo

    https://github.com/kurtdekker/makegeo

    https://gitlab.com/kurtdekker/makegeo

    https://sourceforge.net/p/makegeo
     
    Gamadrila likes this.
  5. ZBerm

    ZBerm

    Joined:
    Jan 12, 2017
    Posts:
    61
    Hey @Gamadrila here's another way to do this, if it suits your game.

    Set up a second camera with the same settings as your player's camera, have it be a child of the main camera and reset it's transform so they're stacked on-top of each other.

    upload_2022-4-3_18-2-56.png

    Set the Overlay Camera's properties like so:
    • Clear Flags: Depth Only
    • Culling Mast: UI (any layer you want to use for this)
    • Depth 1 (Just needs to be higher than the Depth of the main camera)
    upload_2022-4-3_18-4-49.png

    Use a Line Renderer for the line, and set it's Layer to UI (or whatever layer you set on the overlay camera)

    upload_2022-4-3_18-7-39.png

    Now in the game view, you should see that the line is always being rendered on-top of all other geometry in the scene.
    In this example I'm using Unity Terrain, the line does clip though the terrain but the Overlay Camera is still drawing it on-top.
    upload_2022-4-3_18-11-45.png

    If it wasn't clear, this is working because the two cameras in your scene are rendering the exact same picture, however the Overlay Camera will only 'see' objects on the UI layer. And due to the Depth setting on the Cameras the Overlay Camera is drawn over the top of the main camera's image. Guaranteeing that the Line Renderer is always visible, even when it clips though other geometry.

    At sharp angles, or if a box or some other object is in the way of the line, the line will still draw right though it. This may or may not fit into your projects aesthetic.

    Hope this helps.

    You're definitely one of the kool kids ;)
     
    Kurt-Dekker and Gamadrila like this.
  6. Gamadrila

    Gamadrila

    Joined:
    Sep 5, 2021
    Posts:
    142
    I downloaded and looked. But there are no ready-made scenes like as an example. What to do with the "ProjectSettings" folder? As I understand it, this is work with graphics, through code.

    @ZBerm Very suit. Thanks for the detailed tutorial.That's what I did.

    I used this code.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System.Linq;
    5. using UnityEngine.EventSystems;
    6.  
    7. namespace Pathfinding
    8. {
    9.    
    10.     public class AidWar : VersionedMonoBehaviour
    11.     {
    12.         AILerp ai2;
    13.         LineRenderer lin;
    14.  
    15.         GameObject obect;
    16.         public GameObject obecty;
    17.         public Transform pytKon;
    18.         bool warlin = false;
    19.         bool warVkl = false;
    20.  
    21.         GameObject obect2;
    22.         List<Vector3> buffer = new List<Vector3>();
    23.         Vector3 tchk = new Vector3();
    24.         bool mysh = false;
    25.         void OnEnable()
    26.         {
    27.             ai2 = GetComponent<AILerp>();
    28.             ai2.enableRotation = false;
    29.             ai2.canMove = false;
    30.             ai2.canSearch = true;
    31.             lin = GetComponent<LineRenderer>();
    32.             warVkl = true;
    33.             GetComponent<aid>().enabled=false;
    34.         }
    35.  
    36.         void OnDisable()
    37.         {
    38.             warVkl = false;
    39.             buffer.Clear();
    40.             lin.enabled = false;
    41.             Destroy(obect);
    42.             Destroy(obect2);
    43.             ai2.canSearch = false;
    44.             ai2.SetPath(null);
    45.             ai2.canMove = true;
    46.             GetComponent<aid>().enabled = true;
    47.         }
    48.  
    49.  
    50.         void Update()
    51.         {
    52.  
    53.             var dir = ai2.velocity;
    54.             dir.y = 0;
    55.             if (dir != Vector3.zero) ai2.rotation = Quaternion.LookRotation(dir);
    56.             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    57.             RaycastHit hit;
    58.            
    59.             if (Physics.Raycast(ray, out hit, 1000) && hit.collider.gameObject.tag == "zemlya")
    60.             {
    61.  
    62.                 if (warVkl == true)
    63.                 {
    64.                     lin.enabled = true;
    65.                     ai2.destination = hit.point;
    66.                     buffer = new List<Vector3>();
    67.                     ai2.GetRemainingPath(buffer, out bool stale);
    68.                     lin.positionCount = buffer.Count;
    69.                     lin.SetPositions(buffer.ToArray());
    70.                     tchk = new Vector3(buffer.Last().x, 10, buffer.Last().z);
    71.                     if (warlin == false)
    72.                     {
    73.                         obect = Instantiate(obecty, tchk, Quaternion.Euler(90, 0, 0));
    74.                         Destroy(obect2);
    75.                         warlin = true;
    76.                     }
    77.                     else
    78.                     {
    79.                         obect2 = Instantiate(obecty, tchk, Quaternion.Euler(90, 0, 0));
    80.                         Destroy(obect);
    81.                         warlin = false;
    82.                     }
    83.  
    84.                 }
    85.             }
    86.  
    87.             if (!EventSystem.current.IsPointerOverGameObject() && Input.GetMouseButtonDown(0))
    88.             {
    89.                 if (mysh == false)
    90.                 {
    91.                     mysh = true;
    92.                     warVkl = false;
    93.                     lin.enabled = false;
    94.                     Destroy(obect);
    95.                     Destroy(obect2);
    96.                     obect2 = Instantiate(pytKon.gameObject, tchk, Quaternion.Euler(90, 0, 0));
    97.                     ai2.canMove = true;
    98.                                      
    99.                 }
    100.             }
    101.  
    102.             if (ai2.reachedDestination)
    103.             {
    104.                 ai2.SetPath(null);
    105.                 ai2.canMove = false;
    106.                 Destroy(obect2);
    107.                 warVkl = true;
    108.                 mysh = false;
    109.             }
    110.         }
    111.  
    112.              
    113.     }
    114. }
    115.  
    I have a huge stock of FPS in the project, but this method works quite slowly. I have a huge stock of FPS in the project, but this method works quite slowly. Is there any way to make this script work in 1/4 frame? That is, in one frame it could work 4 times.

    The next thing I need to do now is to somehow calculate the character's movement distance and make a step bar. How can I do that?
     
  7. ZBerm

    ZBerm

    Joined:
    Jan 12, 2017
    Posts:
    61
    Hmm, if there's a performance issue you'll have to play around and figure out where you can optimise yourself. But if you just want the same block of code to run 4 times you could just wrap it in a for loop.

    Code (CSharp):
    1. Update() {
    2.   for (int i=0; i < 4; i++) {
    3.  
    4.     // All your code
    5.  
    6.   }
    7. }
    As for the movement distance and step bar, it looks like you already have path finding, you could access the node's value or something. You'll have to figure that out as well, or post a new thread to the forums specifically asking about your path finding.

    Good luck!
     
  8. Gamadrila

    Gamadrila

    Joined:
    Sep 5, 2021
    Posts:
    142
    If the performance is calculated in FPS, then I have no problems with it. I created a topic about this, 360 FPS and overheating of the video card. They told me to reduce it to 60 with a code. At the same time, vertical synchronization does not work.

    I tried through the I<500 cycle, only then the FPS began to drop below 60. However, my computer is not the best. Now I understand how much code I can generate approximately before the FPS drops. But it didn't fix the problem.

    The video is probably bad. The problem is that the display of the path goes in strong jerks.I don't know why this is so. This is how the library works and nothing can be done about it, or my code is bad.

    The "old guard" made such games that now it's hard to repeat even with such technologies.:)
     
  9. Gamadrila

    Gamadrila

    Joined:
    Sep 5, 2021
    Posts:
    142
    I fixed the script!!! I was looking on the forum for how to calculate the length of a path and accidentally came across a description of the "SearchPath()" function. It turns out that the path is not calculated immediately, you need to manually prescribe what would happen right away.
    It is necessary to call the function after assigning the path and that's it.
    Code (CSharp):
    1.  ai2.destination = hit.point;
    2. ai2.SearchPath();
     
    ZBerm likes this.