Skip to content

Commit

Permalink
Merge pull request #47 from Alpha-Blend-Interactive/add-runtime-mesh-…
Browse files Browse the repository at this point in the history
…gen-example

Added example for runtime mesh generation using Lua
  • Loading branch information
loliwut authored Jan 3, 2025
2 parents d72b362 + f97efee commit 518717e
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 2 deletions.
3 changes: 2 additions & 1 deletion docs/cck/lua/examples/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ nav:
- player-profile-picture.md
- player-thumbs-up-launch.md
- player-teleport-away-from-water.md
- runtime-mesh-gen.md
- viewpoint-raycast.md
- persistence.md
- persistence.md
3 changes: 2 additions & 1 deletion docs/cck/lua/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ Here are some example scripts that can be used as an example to learn about Lua.
* [Thumbs Up Player Launcher](player-thumbs-up-launch.md) - Launch upward when doing 2x thumbs up gesture.
* [Viewpoint Raycast](viewpoint-raycast.md) - Perform a raycast from the player's viewpoint.
* [Player Profile / Avatar Picture](player-profile-picture.md) - Get Player Profile and Avatar pictures.
* [Persistence](persistence.md) - Store all kinds of data on the user's PC.
* [Persistence](persistence.md) - Store all kinds of data on the user's PC.
* [Runtime Mesh Generation (Wobbly Cube)](runtime-mesh-gen.md) - Generate a wobbly cube in runtime.
193 changes: 193 additions & 0 deletions docs/cck/lua/examples/runtime-mesh-gen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# Runtime Mesh Generation (Wobbly Cube)

This shows how to create a Cube mesh, and assign it to a mesh renderer and a collider, just from code. It also moves
the vertices around every frame in a wobbly movement.

Mesh generation can only run on world scripts.

This example is a bit silly because we're updating a mesh in the update loop (which is performance heavy). You should
not update meshes every frame, instead you should focus on generating things and then keeping them static.

We're also doing a bit of a hack enabling and disabling the mesh collider component, so it forces an update. Otherwise
the new collision shape won't register.

For this example we require to assign a MeshFilter as `meshFilter` and a MeshCollider component as `meshCollider` to the
Bound Objects. Note these are components, not gameObjects. If you want to use gameObjects, edit the code to perform a
GetComponent.


```lua

UnityEngine = require "UnityEngine"

-- Variables to store mesh data
local mesh = nil
local meshCollider = nil
local vertices = nil
local originalVertices = nil

-- Configurable parameters
local wobbleStrength = 0.5
local wobbleSpeed = 2.0

function Start()

-- Save a reference of our mesh collider, so we can force it to update
meshCollider = BoundObjects.meshCollider

if not meshCollider then
Script.Destroy("No MeshCollider component found!")
return
end

local meshFilter = BoundObjects.meshFilter

if not meshFilter then
Script.Destroy("No MeshFilter component found!")
return
end

-- Create an empty mesh
mesh = UnityEngine.Mesh()

-- Create cube vertices (24 vertices, 4 for each face)
vertices = {
-- Front face
UnityEngine.NewVector3(-0.5, -0.5, 0.5), -- Bottom Left
UnityEngine.NewVector3( 0.5, -0.5, 0.5), -- Bottom Right
UnityEngine.NewVector3( 0.5, 0.5, 0.5), -- Top Right
UnityEngine.NewVector3(-0.5, 0.5, 0.5), -- Top Left

-- Right face
UnityEngine.NewVector3( 0.5, -0.5, 0.5), -- Bottom Left
UnityEngine.NewVector3( 0.5, -0.5, -0.5), -- Bottom Right
UnityEngine.NewVector3( 0.5, 0.5, -0.5), -- Top Right
UnityEngine.NewVector3( 0.5, 0.5, 0.5), -- Top Left

-- Back face
UnityEngine.NewVector3( 0.5, -0.5, -0.5), -- Bottom Left
UnityEngine.NewVector3(-0.5, -0.5, -0.5), -- Bottom Right
UnityEngine.NewVector3(-0.5, 0.5, -0.5), -- Top Right
UnityEngine.NewVector3( 0.5, 0.5, -0.5), -- Top Left

-- Left face
UnityEngine.NewVector3(-0.5, -0.5, -0.5), -- Bottom Left
UnityEngine.NewVector3(-0.5, -0.5, 0.5), -- Bottom Right
UnityEngine.NewVector3(-0.5, 0.5, 0.5), -- Top Right
UnityEngine.NewVector3(-0.5, 0.5, -0.5), -- Top Left

-- Top face
UnityEngine.NewVector3(-0.5, 0.5, 0.5), -- Bottom Left
UnityEngine.NewVector3( 0.5, 0.5, 0.5), -- Bottom Right
UnityEngine.NewVector3( 0.5, 0.5, -0.5), -- Top Right
UnityEngine.NewVector3(-0.5, 0.5, -0.5), -- Top Left

-- Bottom face
UnityEngine.NewVector3(-0.5, -0.5, -0.5), -- Bottom Left
UnityEngine.NewVector3( 0.5, -0.5, -0.5), -- Bottom Right
UnityEngine.NewVector3( 0.5, -0.5, 0.5), -- Top Right
UnityEngine.NewVector3(-0.5, -0.5, 0.5) -- Top Left
}

-- Create triangles (faces)
local triangles = {
-- Front face
0, 1, 2, 0, 2, 3,
-- Right face
4, 5, 6, 4, 6, 7,
-- Back face
8, 9, 10, 8, 10, 11,
-- Left face
12, 13, 14, 12, 14, 15,
-- Top face
16, 17, 18, 16, 18, 19,
-- Bottom face
20, 21, 22, 20, 22, 23
}

-- Create normals (pointing outward)
local normals = {
-- Front face normals (pointing forward)
UnityEngine.NewVector3(0, 0, 1),
UnityEngine.NewVector3(0, 0, 1),
UnityEngine.NewVector3(0, 0, 1),
UnityEngine.NewVector3(0, 0, 1),

-- Right face normals (pointing right)
UnityEngine.NewVector3(1, 0, 0),
UnityEngine.NewVector3(1, 0, 0),
UnityEngine.NewVector3(1, 0, 0),
UnityEngine.NewVector3(1, 0, 0),

-- Back face normals (pointing back)
UnityEngine.NewVector3(0, 0, -1),
UnityEngine.NewVector3(0, 0, -1),
UnityEngine.NewVector3(0, 0, -1),
UnityEngine.NewVector3(0, 0, -1),

-- Left face normals (pointing left)
UnityEngine.NewVector3(-1, 0, 0),
UnityEngine.NewVector3(-1, 0, 0),
UnityEngine.NewVector3(-1, 0, 0),
UnityEngine.NewVector3(-1, 0, 0),

-- Top face normals (pointing up)
UnityEngine.NewVector3(0, 1, 0),
UnityEngine.NewVector3(0, 1, 0),
UnityEngine.NewVector3(0, 1, 0),
UnityEngine.NewVector3(0, 1, 0),

-- Bottom face normals (pointing down)
UnityEngine.NewVector3(0, -1, 0),
UnityEngine.NewVector3(0, -1, 0),
UnityEngine.NewVector3(0, -1, 0),
UnityEngine.NewVector3(0, -1, 0)
}

-- Store original vertices positions
originalVertices = {}
for i = 1, #vertices do
originalVertices[i] = UnityEngine.NewVector3(vertices[i].x, vertices[i].y, vertices[i].z)
end

-- Set the mesh data
mesh.vertices = vertices
mesh.triangles = triangles
mesh.normals = normals

-- Assign the created mesh instance, to both the mesh filter and mesh collider
meshFilter.mesh = mesh
meshCollider.sharedMesh = mesh

print("Cube Mesh created and Wobble initialized successfully! Vertice Count: " .. tostring(#vertices))

end

function Update()
if not mesh or not originalVertices then return end

-- Update vertices using original positions
for i = 1, #vertices do
local originalVertex = originalVertices[i]

-- Calculate wobble based on original position
local wobble = math.sin(UnityEngine.Time.time * wobbleSpeed + originalVertex.x) * wobbleStrength

-- Create new vertex position based on original position
vertices[i] = UnityEngine.NewVector3(
originalVertex.x,
originalVertex.y + wobble,
originalVertex.z
)
end

-- Apply vertices to mesh
mesh.vertices = vertices

-- Force mesh collider to update
-- We need to do this to force the collider to update with the mesh changes
meshCollider.enabled = false
meshCollider.enabled = true
end

```

0 comments on commit 518717e

Please sign in to comment.