Search Unity

RunTime hole

Discussion in 'Scripting' started by horatiu_danciu, Jul 25, 2019.

  1. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    So, i've wanted to do a hole.io game copy just for me . I've writen the code, but when i'm trying to move the hole, the entire circle moves so fast that i can barely see.
    This is the scene: unity.png


    And this is the code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class movement : MonoBehaviour
    6. {
    7.     [Header(" Detection ")]
    8.     public float detectionRadius;
    9.  
    10.     [Header(" Mesh ")]
    11.     public MeshFilter filter;
    12.     public MeshCollider meshCollider;
    13.     Mesh mesh;
    14.     List<int> vertIndexes;
    15.     List<Vector3> offsets;
    16.     float hajm = 1;//make the hole bigger and smaller
    17.  
    18.  
    19.     void Start()
    20.     {
    21.         vertIndexes = new List<int>();
    22.         offsets = new List<Vector3>();
    23.         mesh = filter.mesh;
    24.  
    25.         for (int i = 0; i < mesh.vertices.Length; i++)
    26.         {
    27.  
    28.             float distance = Vector3.Distance(Vector3.zero, mesh.vertices[i]);            
    29.             //Debug.Log(distance);
    30.  
    31.             if (distance < detectionRadius)
    32.             {
    33.                 vertIndexes.Add(i);
    34.                 offsets.Add(mesh.vertices[i] - transform.position);
    35.  
    36.             }
    37.         }
    38.  
    39.  
    40.     }
    41.  
    42.     void Update()
    43.     {
    44.         Vector3[] vertices = mesh.vertices;
    45.  
    46.         for (int i = 0; i < vertIndexes.Count; i++)
    47.         {
    48.             //vertices[vertIndexes[i]].y -= Time.deltaTime;
    49.             vertices[vertIndexes[i]] = transform.position + offsets[i] * hajm;
    50.         }
    51.  
    52.         mesh.vertices = vertices;
    53.         filter.mesh = mesh;
    54.         meshCollider.sharedMesh = mesh;
    55.  
    56.         if (Input.GetKey(KeyCode.S))
    57.             hajm += 0.1f;
    58.         else if (Input.GetKey(KeyCode.D))
    59.             hajm -= 0.1f;
    60.     }
    61.  
    62.     private void OnDrawGizmos()
    63.     {
    64.         Gizmos.color = Color.red;
    65.         Gizmos.DrawWireSphere(transform.position, detectionRadius);
    66.     }
    67.  
    68. }
    69.  
    I've created a sphere that will move in RunTime, and restore the mesh, but that didn't worked as planed. I'm just a 9th class student who likes 3d modeling and unity so please have patience. Also srry for any mistaakes. Thanks!
     

    Attached Files:

    • c#.png
      c#.png
      File size:
      169 KB
      Views:
      578
    Last edited: Jul 25, 2019
  2. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Welcome to to world of game development and working with Unity! A note on forum etiquette: in the future, don't post screenshots of code, copy the text of the code and place it in code tags in your post. Screenshots can be hard to read for different people on different devices, and image hosting sites usually don't host the images forever, which can break the post for people years down the line. https://forum.unity.com/threads/using-code-tags-properly.143875/
    One problem I notice is in your start method, when you are calculating offsets, you are checking the distance from a mesh vertex to your transform position. A vertex from a mesh is a point *relative to that object's transform*, while your transform position is a point *relative to the world origin*. We would say "the vertex is specified in object-space" and "position is in world-space". Because those two vectors are in different spaces, computing the distance between them doesn't work; the Distance method assumes they are in the same space and calculates the distance in that space. To see that, place your game object at (0,0,0) and Debug.Log the distance on line 27, after you calculate. Play the game and note the values. Then, move the object to (10,0,0) and play again. You should see that the distances aren't the same.
    To fix that, you need to convert the vectors you are comparing into the same space. In your case, you want to convert into local space, since that's what the vertices are already in. Fortunately, converting transform.position into the transform's local space is easy: it's (0,0,0). By definition, the transform's position is the origin of its local space. So now, you would write
    float distance = Vector3.Distance(Vector3.zero, meshVerticies[i]);
    . This can be simplified to just
    float distance = meshVerticies[i].magnitude;
    . The magnitude of a vector is just the length of the vector, which is also a point's distance from the origin. If you do the distance check test again, starting at (0,0,0) and trying again at (10,0,0), you should see that the results are the same each time now.
     
    Last edited: Jul 25, 2019
    horatiu_danciu likes this.
  3. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    Thank you so much, and sorry for that screenshot! You solved a big problem for me
     
  4. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    Still working on this. I've change the part you saaid and other ones, and still have the same problem. I even remodeled the circle in blender, and nothing happens. The hole is moving with the circle...This seem tto be tthe biggestt problem i,ve encountered so far.
     
  5. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    If you look at lines 34 and 49, those have the same space-mismatch problem. transform.position is in world-space, but the vertices are in local-space.
    I think I made a mistake. I thought that the mesh was on the same object as the movement script, but that looks like it isn't true. In that case, you still need to do a space change for the transform position, but it isn't as simple as before. Instead of transforming it into its own local space, you have to transform it into the mesh's local space (which are not the same). You can do that by using Transform.InverseTransformPoint. So, distance becomes
    Code (csharp):
    1. Vector3 positionInMeshSpace = filter.transform.InverseTransformPoint(transform.position);
    2. float distance = Vector3.Distance(positionInMeshSpace, meshVerticies[i]);
     
    horatiu_danciu likes this.
  6. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Might be of intrest..

     
    horatiu_danciu likes this.
  7. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    So, i've changed out the code, I remodeled the shape, and now the movement is nice and linear. I'm now able to use the mouse cursor input. But...the hole isn't moving. When i try to move the hole, the circle startts to move too. Here is the new code. Sorry for annoying ya, but I'm a self taught, and I try to learn as much as I can.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class movement : MonoBehaviour
    6. {
    7.     [Header(" Detection ")]
    8.     public float detectionRadius;
    9.  
    10.     [Header(" Mesh ")]
    11.     public MeshFilter filter;
    12.     public MeshCollider meshCollider;
    13.     Mesh mesh;
    14.     List<int> vertIndexes;
    15.     List<Vector3> offsets;
    16.     float hajm = 1;
    17.  
    18.  
    19.     void Start()
    20.     {
    21.         vertIndexes = new List<int>();
    22.         offsets = new List<Vector3>();
    23.         mesh = filter.mesh;
    24.         Vector3 positionInMeshSpace = filter.transform.InverseTransformPoint(transform.position);
    25.         for (int i = 0; i < mesh.vertices.Length; i++)
    26.         {
    27.  
    28.             float distance = Vector3.Distance(positionInMeshSpace, mesh.vertices[i]);
    29.             //Debug.Log(distance);
    30.  
    31.             if (distance < detectionRadius)
    32.             {
    33.                 vertIndexes.Add(i);
    34.                 offsets.Add(mesh.vertices[i] - positionInMeshSpace);
    35.  
    36.             }
    37.         }
    38.  
    39.  
    40.     }
    41.  
    42.     void Update()
    43.     {
    44.         Vector3[] vertices = mesh.vertices;
    45.         Vector3 positionInMeshSpace = filter.transform.InverseTransformPoint(transform.position);
    46.         for (int i = 0; i < vertIndexes.Count; i++)
    47.         {
    48.             //vertices[vertIndexes[i]].y -= Time.deltaTime;
    49.             vertices[vertIndexes[i]] = positionInMeshSpace + offsets[i] * hajm;
    50.         }
    51.  
    52.         mesh.vertices = vertices;
    53.         filter.mesh = mesh;
    54.         meshCollider.sharedMesh = mesh;
    55.  
    56.         if (Input.GetKey(KeyCode.S))
    57.             hajm += 0.1f;
    58.         else if (Input.GetKey(KeyCode.D))
    59.             hajm -= 0.1f;
    60.     }
    61.  
    62.     private void OnDrawGizmos()
    63.     {
    64.         Gizmos.color = Color.red;
    65.         Gizmos.DrawWireSphere(transform.position, detectionRadius);
    66.     }
    67.  
    68. }
    69.  
     
  8. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Do you mean if you hold the S or D key, it doesn't do anything? Otherwise, I don't see any movement code here.
     
    horatiu_danciu likes this.
  9. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    Now it does, but what i'm triyng to do is creating a plane, spawn random objects and be able to move just the hole not tthe entire plane and those object fall right thru. Here is a awfull explanation:
    idkl.png
    After i move the hole the gap dissapear in that place. But my problem is the hole circle moves....thx btw for all the info you gave me!
     
  10. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    How big is your detectionRadius? It might be that you are detecting all the vertices and then moving everything instead of just the inner ones.
     
    horatiu_danciu likes this.
  11. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    The redwiresphere is the detectionradius and it's set to 1. I've tried everything from 0.9 to 3.
     
  12. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Ok, can you post your movement code? I can't see a problem with this part of the code (although that doesn't mean there isn't one!)
     
    Last edited: Jul 25, 2019
  13. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    Well:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class movement : MonoBehaviour
    6. {
    7.     [Header(" Detection ")]
    8.     public float detectionRadius;
    9.  
    10.     [Header(" Mesh ")]
    11.     public MeshFilter filter;
    12.     public MeshCollider meshCollider;
    13.     Mesh mesh;
    14.     List<int> vertIndexes;
    15.     List<Vector3> offsets;
    16.     float hajm = 1;
    17.  
    18.  
    19.     void Start()
    20.     {
    21.         vertIndexes = new List<int>();
    22.         offsets = new List<Vector3>();
    23.         mesh = filter.mesh;
    24.         Vector3 positionInMeshSpace = filter.transform.InverseTransformPoint(transform.position);
    25.         for (int i = 0; i < mesh.vertices.Length; i++)
    26.         {
    27.  
    28.             float distance = Vector3.Distance(positionInMeshSpace, mesh.vertices[i]);
    29.             //Debug.Log(distance);
    30.  
    31.             if (distance < detectionRadius)
    32.             {
    33.                 vertIndexes.Add(i);
    34.                 offsets.Add(mesh.vertices[i] - positionInMeshSpace);
    35.  
    36.             }
    37.         }
    38.  
    39.  
    40.     }
    41.  
    42.     void Update()
    43.     {
    44.         Vector3[] vertices = mesh.vertices;
    45.         Vector3 positionInMeshSpace = filter.transform.InverseTransformPoint(transform.position);
    46.         for (int i = 0; i < vertIndexes.Count; i++)
    47.         {
    48.             //vertices[vertIndexes[i]].y -= Time.deltaTime;
    49.             vertices[vertIndexes[i]] = positionInMeshSpace + offsets[i] * hajm;
    50.         }
    51.  
    52.         mesh.vertices = vertices;
    53.         filter.mesh = mesh;
    54.         meshCollider.sharedMesh = mesh;
    55.  
    56.         if (Input.GetKey(KeyCode.S))
    57.             hajm += 0.1f;
    58.         else if (Input.GetKey(KeyCode.D))
    59.             hajm -= 0.1f;
    60.     }
    61.  
    62.     private void OnDrawGizmos()
    63.     {
    64.         Gizmos.color = Color.red;
    65.         Gizmos.DrawWireSphere(transform.position, detectionRadius);
    66.     }
    67.  
    68. }
    69.  
    this is the only code in the project. I've created an empty gameobject and asigned this(that red sphere). Then created that plane(I've enabled read mesh setting) and asigned the plane to the filter and mesh collider(you can see in a picture above).I don't know what I'm doing wrong.

    This is what i want. a see thru hole thaat moves
     
  14. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    How are you moving the hole?
     
    horatiu_danciu likes this.
  15. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    With my mouse. I'm using tthe xy axis of the wire sphere.
     
  16. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Oh I see, you're using the transform's gizmos. In that case, can you tell if the pivot point of the ground plane is moving? That would mean that its transform is moving. If it isn't, then we're moving all the vertices.
     
    horatiu_danciu likes this.
  17. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    when i'm moving the sphere in play mode ,the pivot point of the plane remains the same, even if i move the sphere to god knows where.
    Edit: when i'm moving the pivot point of the plane in play mode, the plane doesn't moves.
     
  18. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Ok, that means that we're moving all the vertices, despite what it might seem that detectionRadius is saying. Hmm, it may be related to the model scale of the circle. I see that the transform scale of the ground circle is 100, which makes me think that you are using Maya to make your models and that the import scale is something like 0.01. Try clicking on the circle model in your project and change its file scale to something that lets you keep the transform scale at 1. Right now, what I think is happening is that a detection radius is actually detecting things within a radius of 100.
     
    horatiu_danciu likes this.
  19. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    I've tryed with maya and with blender.
     
  20. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    maybe it helps.png this is the wireframe view..maybe it helps
     
  21. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Try setting (in the inspector) detection radius to 0.01. If that works, then what you can do is set the plane transform's scale to 1, then select the model in the project (not the scene hierarchy) and change the Scale Factor to 100.
     
    horatiu_danciu likes this.
  22. horatiu_danciu

    horatiu_danciu

    Joined:
    Feb 18, 2019
    Posts:
    12
    Omg...i have no words...it worked....i ve made the scale 1 and detrad 0.09. Ur such a smart guy...but now i have other questions. Can i make a square plane and add thickness aand the hole with boolean, aaand how can i scale it? And another q: how to invert the z axis with y?
     
  23. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Yes, but you have to be careful how you model it. It needs to have the hole in it, and all of the triangles have to be similar to the how they are in the circle; you can't have a grid of triangles, for example.
    Yes, try to do it on your own first and then come back if you can't make any progress.
    Now that you've set the scale factor to match Unity's default scale, you should be able to scale the ground plane normally. Previously, Unity was assuming the model was tiny, now it knows the right scale. The InverseTransformPoint call we make takes care of accounting for scale.
    The easiest thing to do is rotate the model in your modeling program and then re-export it. You might have to try a few times because maya and unity use different coordinate systems, but start by trying to put the "top" of your model along the -y axis in maya. I always forget the right way to rotate it and have to try again, lol.
     
    horatiu_danciu likes this.