Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Jun 14, 2016 at 01:04 AM by Browninge for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by Browninge · May 28, 2016 at 01:20 PM · meshvoxelminecraftmesh rendererparent and child

Why isn't my mesh updating properly?

I'm designing a game that uses "chunks" to store "blocks" similar to Minecraft.

When a block is placed down, it gets its vertices and triangles assigned, as well as the uv vertices (though I don't think I'm doing those properly but that's for another question). It also is assigned as a child to whichever chunk it's in.

There is a Boolean array in the chunk that keeps track of where each block is placed based on relative position. Ex: blockPos[transform.localPosition.x, ---.y, ---.z]

When a block is placed it is also supposed to call a function in the parent which then calls a function in each child to re-evaluate the mesh.

My problem is that the meshes do not update when the ChunkUpdate() function is called. They work properly only on initial placement.

Below is the script attached to the Chunk Object. Below that is the script attached to the Block Object.

 using UnityEngine;
 using System.Collections;
 
 public class ChunkScript : MonoBehaviour {
 
     public bool[,,] blockPos = new bool[10,300,10];
 
 
     public void ChunkUpdate() {
         foreach (Transform child in transform) {
             BlockScript childScript = child.GetComponent<BlockScript>();
             childScript.CreateFaces();
         }
     }
 
 }


Below: Script attached to block object

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 
 
 public class BlockScript : MonoBehaviour {
 
 
     //Code for rendering mesh
     Vector3[] vertices = new Vector3[8];
     List<int> trianglesOne = new List<int>();
     Vector2[] uvs = new Vector2[8];
     Mesh mesh;
 
     public Material wood;
 
     
 
     //Vector3 pos;
     //End of code for rendering mesh
 
     ChunkScript chunkScript;
     public GameObject CoordChecker;
 
     int xPos;
     int yPos;
     int zPos;
 
     void AddComponents() {
         gameObject.AddComponent<MeshFilter>();
         gameObject.AddComponent<MeshRenderer>();
         gameObject.AddComponent<BoxCollider>();
         BoxCollider box = gameObject.GetComponent<BoxCollider>();
         box.size = new Vector3(.99f, .99f, .99f);
         mesh = GetComponent<MeshFilter>().mesh;
         if (GlobalVariableHolder.wood) gameObject.GetComponent<MeshRenderer>().material = wood;
 
         gameObject.tag = "Block";
     }
     void Start() {
 
 
         AddComponents();
     }
 
     public void printName() {
         print(name);
     }
 
     void OnTriggerEnter(Collider other) {
         if (other.tag == "Chunk") {
             transform.parent = other.transform;
 
             xPos = (int)transform.localPosition.x;
             yPos = (int)transform.localPosition.y;
             zPos = (int)transform.localPosition.z;
 
             transform.name = (xPos + " " + yPos + " " + zPos);
             
 
 
             chunkScript = transform.parent.GetComponent<ChunkScript>();
             chunkScript.blockPos[xPos, yPos, zPos] = true;
             CreateFaces();
             chunkScript.ChunkUpdate();
         }
     }
 
     void OnDestroy() {
         chunkScript.blockPos[xPos, yPos, zPos] = false;
         chunkScript.ChunkUpdate();
     }
 
 
     //Checks if each direction has a block and calls the respective function to draw the face
     public void CreateFaces() {
         mesh.Clear();
         Vertices();
 
         if (zPos < 9) {
             if (chunkScript.blockPos[xPos, yPos, zPos + 1] == false) FaceNorth();
         } else if(zPos == 9) {
             GameObject checker = Instantiate(CoordChecker, new Vector3(xPos, yPos, zPos + 1), Quaternion.identity) as GameObject;
             CoordCheckerScript checkerScript = checker.GetComponent<CoordCheckerScript>();
             if (checkerScript.containsBlock == false) { FaceNorth(); }
             Destroy(checker.gameObject);
         }
 
         if (xPos < 9) {
             if (!chunkScript.blockPos[xPos + 1, yPos, zPos]) FaceEast();
         } else if(xPos == 9) {
             GameObject checker = Instantiate(CoordChecker, new Vector3(xPos + 1, yPos, zPos), Quaternion.identity) as GameObject;
             CoordCheckerScript checkerScript = checker.GetComponent<CoordCheckerScript>();
             if (checkerScript.containsBlock == false) { FaceEast(); }
             Destroy(checker.gameObject);
         }
 
         if (zPos > 0) {
             if (!chunkScript.blockPos[xPos, yPos, zPos - 1]) FaceSouth();
         } else if(zPos == 0) {
             GameObject checker = Instantiate(CoordChecker, new Vector3(xPos, yPos, zPos - 1), Quaternion.identity) as GameObject;
             CoordCheckerScript checkerScript = checker.GetComponent<CoordCheckerScript>();
             if (checkerScript.containsBlock == false) { FaceSouth(); }
             Destroy(checker.gameObject);
         }
 
         if (xPos > 0) {
             if (!chunkScript.blockPos[xPos - 1, yPos, zPos]) FaceWest();
         } else if (xPos == 0) {
             GameObject checker = Instantiate(CoordChecker, new Vector3(xPos - 1, yPos, zPos), Quaternion.identity) as GameObject;
             CoordCheckerScript checkerScript = checker.GetComponent<CoordCheckerScript>();
             if (checkerScript.containsBlock == false) { FaceWest(); }
             Destroy(checker.gameObject);
         }
 
         if (yPos < 299) {
             if (!chunkScript.blockPos[xPos, yPos + 1, zPos]) FaceTop();
         }
 
         if (yPos > 0) {
             if (!chunkScript.blockPos[xPos, yPos - 1, zPos]) FaceBottom();
         }
 
         int[] triangles = trianglesOne.ToArray();
         mesh.triangles = triangles;
 
     }
 
     //Code to set mesh triangles
     void Vertices() {
         vertices[0] = new Vector3(-0.5f, -0.5f, -0.5f);
         vertices[1] = new Vector3(-0.5f, 0.5f, -0.5f);
         vertices[2] = new Vector3(0.5f, 0.5f, -0.5f);
         vertices[3] = new Vector3(0.5f, -0.5f, -0.5f);
 
         vertices[4] = new Vector3(-0.5f, -0.5f, 0.5f);
         vertices[5] = new Vector3(-0.5f, 0.5f, 0.5f);
         vertices[6] = new Vector3(0.5f, 0.5f, 0.5f);
         vertices[7] = new Vector3(0.5f, -0.5f, 0.5f);
 
         mesh.vertices = vertices;
 
         for(int i = 0; i < vertices.Length; i++) {
             uvs[i] = new Vector2(vertices[i].x, vertices[i].z);
         }
         mesh.uv = uvs;
     }
 
     void FaceNorth() {
         trianglesOne.Add(7);
         trianglesOne.Add(6);
         trianglesOne.Add(5);
         trianglesOne.Add(7);
         trianglesOne.Add(5);
         trianglesOne.Add(4);
         
     }
     void FaceEast() {
         trianglesOne.Add(3);
         trianglesOne.Add(2);
         trianglesOne.Add(6);
         trianglesOne.Add(3);
         trianglesOne.Add(6);
         trianglesOne.Add(7);
     }
     void FaceSouth() {
         trianglesOne.Add(0);
         trianglesOne.Add(1);
         trianglesOne.Add(2);
         trianglesOne.Add(0);
         trianglesOne.Add(2);
         trianglesOne.Add(3);
     }
     void FaceWest() {
         trianglesOne.Add(4);
         trianglesOne.Add(5);
         trianglesOne.Add(1);
         trianglesOne.Add(4);
         trianglesOne.Add(1);
         trianglesOne.Add(0);
     }
     void FaceTop() {
         trianglesOne.Add(1);
         trianglesOne.Add(5);
         trianglesOne.Add(6);
         trianglesOne.Add(1);
         trianglesOne.Add(6);
         trianglesOne.Add(2);
     }
     void FaceBottom() {
         trianglesOne.Add(4);
         trianglesOne.Add(0);
         trianglesOne.Add(3);
         trianglesOne.Add(4);
         trianglesOne.Add(3);
         trianglesOne.Add(7);
     }


The If statements in BlockScript check for adjacent blocks inside the chunk as well as outside the chunk.

Any help is appreciated!

EDIT I removed the mesh.clear in the ChunkScript because I clear the mesh in BlockScript.CreateFaces();

EDIT TWO I also commented out "CreateFaces();" in BlockScript.OnTriggerEnter() because of the redundancy in calling CreateFaces() and then calling ChunkScript.ChunkUpdate() which then calls CreateFaces();

EDIT THREE I added a call to ChunkScript.ChunkUpdate() in BlockScript.OnDestroy(); After testing with that line of code, I notice something:

Example One: Place A down, then place B down to east of A: A has all sides rendered, B has all sides rendered but west side;

Example Two: Place A down, then place B down to east of A, then delete A: A has all sides rendered originally, B has all sides but west rendered originally, Upon deletion of A, B has all sides rendered;

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

  • Sort: 
avatar image
0
Best Answer

Answer by Browninge · Jun 03, 2016 at 12:18 PM

For anyone who is having similar problems to what I am(was, rather) having, I will explain the source of my problem and how I solved it.

Since I only wanted to generate certain faces, I would push the triangle vertices to a list under each Face[Direction]() function. I would then generate an array from that list. In order to "undraw" a face that has already been drawn, you have to clear the list that you stored the triangles in originally (for my particular situation, I just had to add in "trianglesOne.Clear();" at the start of my CreateFaces() function.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Glurth · May 28, 2016 at 03:11 PM

It looks like you clear the array in the mesh filter, and generate a new mesh, stored in the BlockScript class. However, I do NOT see where you re-assign that computed mesh BACK to the mesh filter. Until you do so, (assuming the object also has a MeshRenderer), you will not be able to see it, since nothing is assigned to render it.

(p.s. for your initial loop, rather than transform.children, take a look at GetComponentsInChildren(). This can get all the MeshFilters of children, into an array for looping. Eliminates need to check for components against null, something you are not doing in that loop, but probably should..)

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Browninge · May 29, 2016 at 08:37 AM 0
Share

I'm not picking up what you're putting down. From my understanding, BlockScript.CreateFaces() handles everything from declaring the vertices, deter$$anonymous$$ing what sides to generate, declaring the triangles, and then assigning those triangles to the mesh. What exactly happens upon initial placement that doesn't happen upon subsequent calls to BlockScript.CreateFaces()?

Also, I edited a few lines of code and I state exactly what I changed at the bottom of my original post. Everything still works exactly as it did before though, $$anonymous$$us a couple redundant calls.

Also again, I played around changing Line 81 from ...FaceNorth(); to ...print(name + " North is free"); to test that it correctly rechecks the Boolean. I have confirmed that it does work properly on initial placement and subsequent calls to BlockScript.CreateFaces().

avatar image Browninge · May 29, 2016 at 09:27 AM 0
Share

I ask that you check the third edit that I made (I state what I changed at the end of the original post). The current situation leads me to suspect that somehow a block doesn't register subsequently placed adjacent blocks, even though it registers the deletion of adjacent blocks that were placed prior. However, my original comment to your reply suggests that blocks do register subsequently placed adjacent blocks.

avatar image Browninge · May 29, 2016 at 09:31 AM 0
Share

I will also add in what you said about GetComponentsInChildren(), but after I figure the current dilemma out.

avatar image Glurth · May 29, 2016 at 04:28 PM 0
Share

Hmm, I may have been incorrect in my suggestion. I was talking about this line:

 mesh = GetComponent<$$anonymous$$eshFilter>().mesh;

Which is how you get the $$anonymous$$esh you want to work with. I guess if you adjust THIS mesh, it wont need to be reassignned. This threw me off, because normally, I would create a NEW mesh, using new $$anonymous$$esh(), and then after building it, assign THAT to the $$anonymous$$eshFilter component.

 GetComponent<$$anonymous$$eshFilter>().mesh= newlyCreated$$anonymous$$esh;

Perhaps this is related to the issue in a different way I expected though. You mentioned that edit three caused changes in existsing meshes. Perhaps the mesh you are getting and modifying is actually in use by the unexpectedly modified object? If so, you probably DO want to create a new mesh for each block, as mentioned above..

avatar image Browninge Glurth · May 30, 2016 at 06:24 AM 0
Share

I understand exactly what you're saying and will play around with that and get back to you.

avatar image Browninge · Jun 02, 2016 at 04:44 AM 0
Share

WAIT A $$anonymous$$INUTE I THIN$$anonymous$$ I $$anonymous$$NOW WHAT IS WRONG. I am pretty sure the issue comes from me not clearing the triangle list/array. I think that's my problem.

Show more comments

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Voxel C# source problems. 1 Answer

How to assign texture to a specific mesh in a chunk for a minecraft game? 1 Answer

Create vertices marching cubes 0 Answers

Minecraft clone, how to randomly generate a voxel landmass? 1 Answer

Mesh from MagicaVoxel cast a strange holed shadow 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges