Search Unity

Getting the properties of nearby vertices based on where on the screen you touch

Discussion in 'Scripting' started by Wantcha, Mar 26, 2019.

  1. Wantcha

    Wantcha

    Joined:
    Dec 2, 2017
    Posts:
    114
    I would like to implement this mechanic in my game where if you touch a mesh, the nearby vertices get affected in a certain radius that applies an effect on them. How could I access those nearby vertices when touching the screen?
     
  2. mjzx

    mjzx

    Joined:
    Aug 18, 2013
    Posts:
    114
    You could try get each vertex of the mesh with the Mesh.GetVertices method, convert each of those world-space positions to screen-space with Camera.WorldToScreenPoint, and then have a nested for-loop, iterating through the touches on the screen, and checking if any touch positions are within a certain distance from a vertex. (with Vector2.Distance)

    From there you should be able to work out what to do.

    Apologies if this answer isn't quite clear. Feel free ask if you need any clarification.
     
  3. Wantcha

    Wantcha

    Joined:
    Dec 2, 2017
    Posts:
    114
    I can see why this would work, but checking every frame for the distance of every single vertex in screen space to the current touch sounds way too performance-intensive. This is for a mobile app, I need something more efficient.
     
  4. mjzx

    mjzx

    Joined:
    Aug 18, 2013
    Posts:
    114
    Yeah I forgot this would be for a mobile game.
    I guess most manipulation of any vertex is quite expensive. I honestly cannot think of any other ways to implement this. Sorry about that.

    If you truly cannot solve this, maybe give my idea a shot, and see how it runs on mobile. As long as you cache the positions of the vertices into some kind of array, it shouldn't be too bad. (Mobile-phone processors have become much more advanced compared to what they once were.) Though you should try keep the poly-count of each object quite low. And only iterate the array when the touch count is greater than zero. Also try keep the number of objects that have this vertex-manipulation-feature to an absolute minimum.

    Hopefully someone else with a little more creativity than me has some better ideas.
     
  5. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    You don't need to check all vertices on the screen. Using event system, you can narrow down your search to a single mesh. If there aren't many thousands of vertices, it may work fast enough even on mobile device. For 1000 vertices mesh you won't notice anything on mobile device. And if it still too slow for you, you may try different approach. Push the touch position to the shader parameter and apply your modifications to vertices inside the vertex shader. This will go faster than light.
     
  6. Wantcha

    Wantcha

    Joined:
    Dec 2, 2017
    Posts:
    114
    And how will I compare the position from the touch to the mesh's vertices in the shadergraph?
     
  7. mjzx

    mjzx

    Joined:
    Aug 18, 2013
    Posts:
    114
    palex-nx's solution seems quite interesting. Though it would most likely only be able to support 1 touch. (I'm don't think it's possible to set an array as a shader param.)

    Assuming this isn't a problem, you may be able to convert the touch position to world space, and in the vertex shader compare the distance between the vertex and touch position with some constant. (Try avoid if-else statements in shaders, and instead use the ternary operator when possible as it is supposably more performant.)
    If the distance is less than the defined constant then you could set the vertex position to the touch position.

    The problem with this though is the fact that it is in 3 dimensions. So converting the touch position to world space may not always have the same depth as the vertex. This could possibly be resolved though I cannot currently think of any ways to do so, may need to search around or do some testing.

    You may also want to find an alternative to using the 'distance' as the distance is calculated through square-rooting each of the positions squared - which I believe may be quite an expensive operation, especially when being called foreach vertex. (Someone feel free to correct me if I'm wrong.)

    Personally I'd use my original idea, in conjunction with palex-nx's EventSystem optimisation as it is a pretty straight-forward approach.
     
  8. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    10 shader parameters will be sufficient, at least for us, humans, but actually arrays are suppported, see here: https://forum.unity.com/threads/passing-array-to-shader.392586/