Skip to content

Instantly share code, notes, and snippets.

@nothke
Last active October 19, 2019 19:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nothke/93c160cb6c56065e5585e3b4e8ccfa77 to your computer and use it in GitHub Desktop.
Save nothke/93c160cb6c56065e5585e3b4e8ccfa77 to your computer and use it in GitHub Desktop.
using System.Collections.Generic;
using u = UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;
using Unity.Entities;
using Unity.Transforms;
using Unity.Rendering;
using Unity.Physics;
public class StackSpawner : u.MonoBehaviour
{
public u.Material material;
public u.Material material2;
public u.Mesh mesh;
public float3 blockDimensions = float3(2, 1, 1);
public int widthBlocks = 6;
public int heightBlocks = 50;
EntityManager manager;
EntityArchetype bodyArchetype;
BlobAssetReference<Collider> boxColliderAsset;
RenderMesh rm;
RenderMesh rm2;
MassProperties cubeMassProperties;
List<Entity> activeBlocks;
void Start()
{
Init();
Spawn();
}
private void Update()
{
if (u.Input.GetKeyDown(u.KeyCode.R))
Respawn();
}
public void Respawn()
{
ClearBlocks();
Spawn();
}
void Spawn()
{
Spawn4Walls(float3(0), widthBlocks, heightBlocks);
}
public void ClearBlocks()
{
for (int i = 0; i < activeBlocks.Count; i++)
{
manager.DestroyEntity(activeBlocks[i]);
}
activeBlocks.Clear();
}
void Init()
{
activeBlocks = new List<Entity>();
manager = World.Active.EntityManager;
bodyArchetype = manager.CreateArchetype(
typeof(LocalToWorld),
typeof(RenderMesh),
typeof(Translation),
typeof(Rotation),
typeof(NonUniformScale),
typeof(PhysicsCollider),
typeof(PhysicsVelocity),
typeof(PhysicsMass),
typeof(PhysicsDamping));
rm = GetRenderMesh(material, mesh);
rm2 = GetRenderMesh(material2, mesh);
boxColliderAsset = BoxCollider.Create(new BoxGeometry()
{
BevelRadius = 0,
Size = blockDimensions,
Center = 0,
Orientation = Unity.Mathematics.quaternion.identity
});
cubeMassProperties = boxColliderAsset.Value.MassProperties;
}
RenderMesh GetRenderMesh(u.Material material, u.Mesh mesh)
{
return new RenderMesh()
{
material = material,
mesh = mesh,
castShadows = u.Rendering.ShadowCastingMode.On,
receiveShadows = true
};
}
void Spawn4Walls(float3 position, int widthBlocks, int heightBlocks)
{
float wallWidth = blockDimensions.x * widthBlocks;
float halfWall = wallWidth * 0.5f;
float y = 0.5f;
SpawnWallStack(position + float3(0, y, halfWall), float3(0, 0, 1), widthBlocks, heightBlocks, 1);
SpawnWallStack(position + float3(halfWall, y, 0), float3(1, 0, 0), widthBlocks, heightBlocks, 1);
SpawnWallStack(position + float3(0, y, -halfWall), float3(0, 0, -1), widthBlocks, heightBlocks, 1);
SpawnWallStack(position + float3(-halfWall, y, 0), float3(-1, 0, 0), widthBlocks, heightBlocks, 1);
}
void SpawnWallStack(float3 position, float3 facingDir, int width, int height, float oddOffset)
{
quaternion rot = Unity.Mathematics.quaternion.LookRotation(facingDir, up());
float3 rightDir = cross(facingDir, up());
float halfWallWidth = (blockDimensions.x * width - oddOffset) * 0.5f;
for (int y = 0; y < height; y++)
{
float h = position.y + y * blockDimensions.y;
float offset = y % 2 == 0 ? 0 : oddOffset;
for (int x = 0; x < width; x++)
{
Entity e = SpawnBlockEntity();
SetPhysics(e);
float w = x * blockDimensions.x + offset;
float3 pos = position + rightDir * (-halfWallWidth + w);
pos.y = h;
SetTransform(e, pos, rot, blockDimensions);
SetRendering(e, u.Random.value > 0.5f ? rm : rm2);
}
}
}
Entity SpawnBlockEntity()
{
Entity e = manager.CreateEntity(bodyArchetype);
activeBlocks.Add(e);
return e;
}
void SetPhysics(Entity e)
{
PhysicsMass mass = PhysicsMass.CreateDynamic(cubeMassProperties, 1);
manager.SetComponentData(e, mass);
manager.SetComponentData(e, new PhysicsCollider() { Value = boxColliderAsset });
manager.SetComponentData(e, new PhysicsDamping() { Linear = 0 });
manager.SetComponentData(e, new PhysicsVelocity() { Linear = 0 });
}
void SetTransform(Entity e, float3 position, quaternion rotation, float3 scale)
{
manager.SetComponentData(e, new Translation() { Value = position });
manager.SetComponentData(e, new Rotation() { Value = rotation });
manager.SetComponentData(e, new NonUniformScale() { Value = scale });
}
void SetRendering(Entity e, RenderMesh rm)
{
manager.SetSharedComponentData(e, rm);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment