public VehicleCreator(Scene scene, Urho.Resources.ResourceCache cache, ScreenInfoRatio screenInfo, Vector2 initPositionHeight) { _screenInfo = screenInfo; _vehicleVerticalOffset += initPositionHeight.Y; // Load vehicle info _vehicleModel = VehicleManager.Instance.SelectedVehicleModel; var l = _vehicleModel.BodyPosition.Left; var t = _vehicleModel.BodyPosition.Top; var r = _vehicleModel.BodyPosition.Right; var b = _vehicleModel.BodyPosition.Bottom; // Get vehicle texture from coordinates var sprite = new Sprite2D { Texture = cache.GetTexture2D("Textures/Garage/vehicles_body.png"), Rectangle = new IntRect(l, t, r, b) }; // Create vehicle main body reference Node box = scene.CreateChild("Box"); StaticSprite2D boxSprite = box.CreateComponent <StaticSprite2D>(); boxSprite.Sprite = sprite; _mainBody = box.CreateComponent <RigidBody2D>(); _mainBody.BodyType = BodyType2D.Dynamic; _mainBody.LinearDamping = 0.2f; _mainBody.AngularDamping = 0.2f; _mainBody.Bullet = true; _mainBody.Mass = 1.0f; //_mainBody.SetMassCenter(new Vector2(-2.1f * _screenInfo.XScreenRatio, -0.1f * _screenInfo.YScreenRatio)); /****************************************/ /* Outer body for collision - null mass */ /****************************************/ float startVX = -1.2f + _vehicleModel.BalanceBodyOffset[0]; float startVY = -0.55f + _vehicleModel.BalanceBodyOffset[1]; float driverXOffset = 1.0f + _vehicleModel.BalanceBodyOffset[2]; VehicleObjectPosition = new Vector3(-0.7f * _screenInfo.XScreenRatio, _vehicleVerticalOffset + _vehicleModel.BalanceBodyOffset[1], 3.0f); // MAIN BODY BOUNDS CollisionChain2D bodyBounds = box.CreateComponent <CollisionChain2D>(); bodyBounds.VertexCount = 9; bodyBounds.SetVertex(0, new Vector2(startVX, startVY)); // BOTTOM LEFT bodyBounds.SetVertex(1, new Vector2(startVX, startVY + 0.1f)); bodyBounds.SetVertex(2, new Vector2(startVX + driverXOffset, startVY + 0.1f)); bodyBounds.SetVertex(3, new Vector2(startVX + driverXOffset, startVY + 0.2f)); bodyBounds.SetVertex(4, new Vector2(startVX + driverXOffset + 0.3f, startVY + 0.2f)); bodyBounds.SetVertex(5, new Vector2(startVX + driverXOffset + 0.3f, startVY + 0.1f)); bodyBounds.SetVertex(6, new Vector2(startVX + driverXOffset + 0.8f, startVY + 0.1f)); bodyBounds.SetVertex(7, new Vector2(startVX + driverXOffset + 0.8f, startVY)); // BOTTOM RIGHT bodyBounds.SetVertex(8, new Vector2(startVX, startVY)); // BOTTOM LEFT bodyBounds.Friction = 1.0f; bodyBounds.Restitution = 0.0f; // BACK BODY BOUND CollisionChain2D backBounds = box.CreateComponent <CollisionChain2D>(); backBounds.VertexCount = 4; backBounds.SetVertex(0, new Vector2(startVX, startVY + 0.1f)); backBounds.SetVertex(1, new Vector2(startVX, startVY + 0.15f)); backBounds.SetVertex(2, new Vector2(startVX + 0.02f, startVY + 0.15f)); backBounds.SetVertex(3, new Vector2(startVX + 0.02f, startVY + 0.1f)); backBounds.SetVertex(4, new Vector2(startVX, startVY + 0.1f)); backBounds.Friction = 1.0f; backBounds.Restitution = 0.0f; // Main body for constraints and mass // Create box shape CollisionBox2D shape = box.CreateComponent <CollisionBox2D>(); // Set size shape.Size = new Vector2(0.32f, 0.32f); shape.Density = 8.0f; // Set shape density (kilograms per meter squared) shape.Friction = 0.8f; // Set friction shape.Restitution = 0.0f; // Set restitution (no bounce) // Update center of collision body - moves center of mass shape.SetCenter(-0.2f, -0.65f); // Create a vehicle from a compound of 2 ConstraintWheel2Ds var car = box; //car.Scale = new Vector3(1.5f * _screenInfo.XScreenRatio, 1.5f * _screenInfo.YScreenRatio, 0.0f); // DEFINES POSITION OF SPRITE AND MAIN BODY MASS car.Position = new Vector3(0.0f * _screenInfo.XScreenRatio, _vehicleVerticalOffset * _screenInfo.YScreenRatio, 1.0f); /*****************/ /* DEFINE WHEELS */ /*****************/ var wheelSprites = new List <Sprite2D>(); foreach (var w in _vehicleModel.WheelsPosition) { wheelSprites.Add(new Sprite2D { Texture = cache.GetTexture2D("Textures/Garage/vehicles_wheels.png"), Rectangle = new IntRect(w.Left, w.Top, w.Right, w.Bottom) }); } // Create a ball (will be cloned later) Node ball1WheelNode = scene.CreateChild("Wheel"); StaticSprite2D ballSprite = ball1WheelNode.CreateComponent <StaticSprite2D>(); ballSprite.Sprite = wheelSprites[0]; ball1WheelNode.Scale = new Vector3(_vehicleModel.WheelsSize[0], _vehicleModel.WheelsSize[0], 1.0f); RigidBody2D ballBody = ball1WheelNode.CreateComponent <RigidBody2D>(); ballBody.BodyType = BodyType2D.Dynamic; ballBody.LinearDamping = 0.1f; ballBody.AngularDamping = 0.1f; ballBody.Bullet = true; ballBody.Mass = 2.0f; // WHEEL COLLISION CollisionCircle2D ballShape = ball1WheelNode.CreateComponent <CollisionCircle2D>(); // Create circle shape ballShape.Radius = 0.14f; // * _vehicleModel.WheelsSize[0]; // Set radius ballShape.Density = 2.0f; // Set shape density (kilograms per meter squared) ballShape.Friction = (_vehicleModel.Wheel / 2) / 10.0f; // Set friction: 1.0 = max friction ballShape.Restitution = (20 - _vehicleModel.Suspensions) / 2 / 10.0f; // Set restitution: make it bounce: 0.0 = no bounce // CLONE AND POSITION WHEELS for (var i = 0; i < _vehicleModel.WheelsBodyPosition.Count; i++) { if (i == 0) { float x1 = _vehicleModel.WheelsBodyPosition[i].X % _vehicleImgPos; float y1 = _vehicleModel.WheelsBodyPosition[i].Y % _vehicleImgPos; x1 = x1 >= _vehicleImgPos / 2 ? (x1 - _vehicleImgPos / 2) * Application.PixelSize : -(_vehicleImgPos / 2 - x1) * Application.PixelSize; y1 = (_vehicleImgPos / 2 - y1) * Application.PixelSize; // WHEEL POSITION - NEEDS TO BE SET RELATIVE TO MAIN BODY ball1WheelNode.Position = new Vector3(x1, y1 + (_vehicleVerticalOffset - 0.05f) * _screenInfo.YScreenRatio, 1.0f); // SET BACK WHEEL CONSTRAINT COMPONENTS var constraintWheel = car.CreateComponent <ConstraintWheel2D>(); constraintWheel.OtherBody = ball1WheelNode.GetComponent <RigidBody2D>(); constraintWheel.Anchor = ball1WheelNode.Position2D; constraintWheel.Axis = new Vector2(0.0f, 1.0f); constraintWheel.MaxMotorTorque = 150.0f; constraintWheel.FrequencyHz = 15.0f; constraintWheel.DampingRatio = 10.0f; constraintWheel.MotorSpeed = 0.0f; _wheelsConstraints.Add(constraintWheel); } else { Node newWheelNode = ball1WheelNode.Clone(CreateMode.Replicated); StaticSprite2D newBallSprite = newWheelNode.CreateComponent <StaticSprite2D>(); newBallSprite.Sprite = wheelSprites.Count > i ? wheelSprites[i] : wheelSprites.Last(); float x2 = _vehicleModel.WheelsBodyPosition[i].X % _vehicleImgPos; float y2 = _vehicleModel.WheelsBodyPosition[i].Y % _vehicleImgPos; x2 = x2 >= _vehicleImgPos / 2 ? (x2 - _vehicleImgPos / 2) * Application.PixelSize : -(_vehicleImgPos / 2 - x2) * Application.PixelSize; y2 = (_vehicleImgPos / 2 - y2) * Application.PixelSize; // Update collision shape CollisionCircle2D collisionShape = newWheelNode.GetComponent <CollisionCircle2D>(); // Create circle shape collisionShape.Radius = 0.14f; // * _vehicleModel.WheelsSize[i]; // WHEEL POSITION - NEEDS TO BE SET RELATIVE TO MAIN BODY newWheelNode.Scale = new Vector3(_vehicleModel.WheelsSize[i], _vehicleModel.WheelsSize[i], 1.0f); newWheelNode.Position = new Vector3(x2, y2 + (_vehicleVerticalOffset - 0.05f) * _screenInfo.YScreenRatio, 1.0f); // SET FRONT WHEEL CONSTRAINT COMPONENTS var constraintWheel = car.CreateComponent <ConstraintWheel2D>(); constraintWheel.OtherBody = newWheelNode.GetComponent <RigidBody2D>(); constraintWheel.Anchor = newWheelNode.Position2D; constraintWheel.Axis = new Vector2(0.0f, 1.0f); constraintWheel.MaxMotorTorque = 150.0f; constraintWheel.FrequencyHz = 15.0f; constraintWheel.DampingRatio = 10.0f; constraintWheel.MotorSpeed = 0.0f; _wheelsConstraints.Add(constraintWheel); } } }
void GenerateChunk(int startx) { // We create a node and position where the chunk starts Node node = _scene.CreateChild(); node.SetPosition2D(startx, 0); // We create components to render the geometries of the surface and the ground var groundComponent = node.CreateComponent <CustomGeometry>(); groundComponent.SetMaterial(_chunkmat); groundComponent.BeginGeometry(0, PrimitiveType.TRIANGLE_LIST); var surfaceComponent = node.CreateComponent <CustomGeometry>(); surfaceComponent.SetMaterial(_surfMat); surfaceComponent.BeginGeometry(0, PrimitiveType.TRIANGLE_LIST); // We initialize and add a single entry to the surface points list List <Vector2> surface = new List <Vector2>() { new Vector2(0, (float)_noise.Evaluate(startx * NoiseScaleX, 0) * NoiseScaleY ) }; // We translate the last surface extrusion point so it's local relative to the chunk we're creating _lastSurfaceExtrusion += Vector3.Left * Chunksize; // We //TODO continue float incr = SurfaceSegmentSize; for (float i = 0; i < Chunksize - float.Epsilon * 2; i += incr) { float iend = i + incr; float tlY = SampleSurface(startx + i); float trY = SampleSurface(startx + iend); float blY = tlY + Chunkheight; float brY = trY + Chunkheight; Vector3 bl = new Vector3(i, blY, -10); Vector3 tl = new Vector3(i, tlY, -10); Vector3 br = new Vector3(iend, brY, -10); Vector3 tr = new Vector3(iend, trY, -10); //phys surface.Add(new Vector2(tr)); //decor CreateDecor(tr + Vector3.Right * startx, tl - tr); //surface visual Vector2 startV = Vector2.UnitX * (i / Chunksize) * SurfaceRepeatPerChunk; Vector2 endV = Vector2.UnitX * (iend / Chunksize * SurfaceRepeatPerChunk); //bl surfaceComponent.DefineVertex(_lastSurfaceExtrusion); surfaceComponent.DefineTexCoord(startV); //tl surfaceComponent.DefineVertex(tl); surfaceComponent.DefineTexCoord(startV - Vector2.UnitY); //tr surfaceComponent.DefineVertex(tr); surfaceComponent.DefineTexCoord(-Vector2.UnitY + endV); //bl surfaceComponent.DefineVertex(_lastSurfaceExtrusion); surfaceComponent.DefineTexCoord(startV); //tr surfaceComponent.DefineVertex(tr); surfaceComponent.DefineTexCoord(-Vector2.UnitY + endV); //br _lastSurfaceExtrusion = tr + Quaternion.FromAxisAngle(Vector3.Back, 90) * Vector3.NormalizeFast(tr - tl); surfaceComponent.DefineVertex(_lastSurfaceExtrusion); surfaceComponent.DefineTexCoord(endV); //ground //bl groundComponent.DefineVertex(bl); groundComponent.DefineTexCoord(new Vector2(bl / Chunksize)); //tl groundComponent.DefineVertex(tl); groundComponent.DefineTexCoord(new Vector2(tl / Chunksize)); //tr groundComponent.DefineVertex(tr); groundComponent.DefineTexCoord(new Vector2(tr / Chunksize)); //bl groundComponent.DefineVertex(bl); groundComponent.DefineTexCoord(new Vector2(bl / Chunksize)); //tr groundComponent.DefineVertex(tr); groundComponent.DefineTexCoord(new Vector2(tr / Chunksize)); //br groundComponent.DefineVertex(br); groundComponent.DefineTexCoord(new Vector2(br / Chunksize)); } surfaceComponent.Commit(); groundComponent.Commit(); CollisionChain2D col = node.CreateComponent <CollisionChain2D>(); col.SetLoop(false); col.SetFriction(10); col.SetVertexCount((uint)surface.Count + 1); _chunks.Add(col); //Vector3 smoother = Quaternion.FromRotationTo(Vector3.Left, new Vector3(-1,-.3f,0)) * new Vector3(surface[0] - surface[1]); //col.SetVertex(0,surface[0] + new Vector2(smoother)); Vector2 smoother = new Vector2(-incr * .5f, (float)_noise.Evaluate((startx - incr * .5f) * NoiseScaleX, 0) * NoiseScaleY - 0.005f); col.SetVertex(0, smoother); uint c2 = 0; foreach (Vector2 surfpoint in surface) { col.SetVertex(++c2, new Vector2(surfpoint.X, surfpoint.Y)); } node.CreateComponent <RigidBody2D>().SetBodyType(BodyType2D.BT_STATIC); }
void GenerateChunk(int startx) { Node n = scene.CreateChild(); n.SetPosition2D(startx, 0); var g = n.CreateComponent <CustomGeometry>(); g.SetMaterial(chunkmat); g.BeginGeometry(0, PrimitiveType.TRIANGLE_LIST); var s = n.CreateComponent <CustomGeometry>(); s.SetMaterial(surfMat); s.BeginGeometry(0, PrimitiveType.TRIANGLE_LIST); List <Vector2> surface = new List <Vector2>() { new Vector2(0, (float)noise.Evaluate((startx) * noiseScaleX, 0) * noiseScaleY ) }; lastSurfaceExtrusion += Vector3.Left * chunksize; float incr = 0.5f; for (float i = 0; i < chunksize - float.Epsilon * 2; i += incr) { float iend = i + incr; float tlY = SampleSurface(startx + i); float trY = SampleSurface(startx + iend); float blY = tlY + chunkheight; float brY = trY + chunkheight; Vector3 bl = new Vector3(i, blY, 0); Vector3 tl = new Vector3(i, tlY, 0); Vector3 br = new Vector3(iend, brY, 0); Vector3 tr = new Vector3(iend, trY, 0); //phys surface.Add(new Vector2(tr)); //decor CreateDecor(tr + Vector3.Right * startx, tl - tr); //surface visual Vector2 startV = Vector2.UnitX * (i / chunksize) * surfaceVisualRepeatPerChunk; Vector2 endV = Vector2.UnitX * (iend / chunksize * surfaceVisualRepeatPerChunk); //bl s.DefineVertex(lastSurfaceExtrusion); s.DefineTexCoord(startV); //tl s.DefineVertex(tl); s.DefineTexCoord(startV - Vector2.UnitY); //tr s.DefineVertex(tr); s.DefineTexCoord(-Vector2.UnitY + endV); //bl s.DefineVertex(lastSurfaceExtrusion); s.DefineTexCoord(startV); //tr s.DefineVertex(tr); s.DefineTexCoord(-Vector2.UnitY + endV); //br lastSurfaceExtrusion = tr + Quaternion.FromAxisAngle(Vector3.Back, 90) * Vector3.NormalizeFast(tr - tl); s.DefineVertex(lastSurfaceExtrusion); s.DefineTexCoord(endV); //ground //bl g.DefineVertex(bl); g.DefineTexCoord(new Vector2(bl / chunksize)); //tl g.DefineVertex(tl); g.DefineTexCoord(new Vector2(tl / chunksize)); //tr g.DefineVertex(tr); g.DefineTexCoord(new Vector2(tr / chunksize)); //bl g.DefineVertex(bl); g.DefineTexCoord(new Vector2(bl / chunksize)); //tr g.DefineVertex(tr); g.DefineTexCoord(new Vector2(tr / chunksize)); //br g.DefineVertex(br); g.DefineTexCoord(new Vector2(br / chunksize)); } s.Commit(); g.Commit(); CollisionChain2D col = n.CreateComponent <CollisionChain2D>(); col.SetLoop(false); col.SetFriction(10); col.SetVertexCount((uint)surface.Count + 1); chunks.Add(col); //Vector3 smoother = Quaternion.FromRotationTo(Vector3.Left, new Vector3(-1,-.3f,0)) * new Vector3(surface[0] - surface[1]); //col.SetVertex(0,surface[0] + new Vector2(smoother)); Vector2 smoother = new Vector2(-incr * .5f, (float)noise.Evaluate((startx - incr * .5f) * noiseScaleX, 0) * noiseScaleY - 0.005f); col.SetVertex(0, smoother); uint c2 = 0; foreach (Vector2 surfpoint in surface) { col.SetVertex(++c2, new Vector2(surfpoint.X, surfpoint.Y)); } n.CreateComponent <RigidBody2D>().SetBodyType(BodyType2D.BT_STATIC); }
void CreateBackgroundScene() { scene = new Scene(); scene.CreateComponent <Octree>(); scene.CreateComponent <DebugRenderer>(); scene.CreateComponent <PhysicsWorld2D>(); // Create camera node CameraNode = scene.CreateChild("Camera"); // Set camera's position CameraNode.Position = (new Vector3(0.1f, 0.0f, -2.0f)); Camera camera = CameraNode.CreateComponent <Camera>(); camera.Orthographic = true; camera.OrthoSize = (float)graphics.Height * PixelSize; camera.Zoom = 3.5f * Math.Min(screenInfoRatio.XScreenRatio, screenInfoRatio.YScreenRatio); // Create 2D physics world component scene.CreateComponent <PhysicsWorld2D>(); Sprite2D boxSprite = cache.GetSprite2D("Urho2D/Box.png"); // FOREGROUND Sprite2D foregroundSprite = cache.GetSprite2D("Urho2D/foreground.png"); Node foregroundNode = scene.CreateChild("Foreground"); foregroundNode.Position = (new Vector3(0.9f, -1.25f, 0.0f)); foregroundNode.Scale = new Vector3(2.0f, 2.0f, 0.0f); StaticSprite2D foregroundStaticSprite = foregroundNode.CreateComponent <StaticSprite2D>(); foregroundStaticSprite.Sprite = foregroundSprite; // BACKGROUND LAYER 1 Sprite2D bgLayer1Sprite = cache.GetSprite2D("Urho2D/bg_layer1.png"); Node bgLayer1Node = scene.CreateChild("Background_layer1"); bgLayer1Node.Position = (new Vector3(0.9f, -1.25f, 0.1f)); bgLayer1Node.Scale = new Vector3(2.0f, 2.0f, 0.0f); StaticSprite2D bgLayer1StaticSprite = bgLayer1Node.CreateComponent <StaticSprite2D>(); bgLayer1StaticSprite.Sprite = bgLayer1Sprite; // BACKGROUND LAYER 2 Sprite2D backgroundSprite = cache.GetSprite2D("Urho2D/bg_layer2.png"); Node backgroundNode = scene.CreateChild("Background_layer2"); backgroundNode.Position = (new Vector3(0.9f, -1.25f, 0.1f)); backgroundNode.Scale = new Vector3(2.0f, 2.0f, 0.0f); StaticSprite2D backgroundStaticSprite = backgroundNode.CreateComponent <StaticSprite2D>(); backgroundStaticSprite.Sprite = backgroundSprite; // Create ground. Node groundNode = scene.CreateChild("Ground"); groundNode.Position = (new Vector3(0.0f, -3.0f, 0.0f)); //groundNode.Scale = new Vector3(200.0f, 1.0f, 0.0f); // Create 2D rigid body for gound groundNode.CreateComponent <RigidBody2D>(); StaticSprite2D groundSprite = groundNode.CreateComponent <StaticSprite2D>(); groundSprite.Sprite = boxSprite; // CHAIN GROUND CollisionChain2D collisionChain = groundNode.CreateComponent <CollisionChain2D>(); collisionChain.VertexCount = 200; for (var i = 0; i < 200; i++) { Vector2 currVertex; if (i > 0) { currVertex = collisionChain.GetVertex((uint)i - 1); collisionChain.SetVertex((uint)i, new Vector2((i / 2.0f) - 5.0f, currVertex.Y + NextRandom(-0.1f, 0.1f))); } else { collisionChain.SetVertex((uint)i, new Vector2((i / 2.0f) - 5.0f, NextRandom(-0.1f, 0.1f))); } } collisionChain.Friction = 0.3f; // Set friction collisionChain.Restitution = 0.0f; // Set restitution (no bounce) // FLAT BOX GROUND // Create box collider for ground //CollisionBox2D groundShape = groundNode.CreateComponent<CollisionBox2D>(); // Set box size //groundShape.Size = new Vector2(0.32f, 0.32f); }
void GenerateChunk(int startx) { // We create a node and position where the chunk starts Node node = _scene.CreateChild(); node.SetPosition2D(startx, 0); // We create components to render the geometries of the surface and the ground var groundComponent = node.CreateComponent <CustomGeometry>(); groundComponent.SetMaterial(_chunkMaterial); groundComponent.BeginGeometry(0, PrimitiveType.TRIANGLE_LIST); var surfaceComponent = node.CreateComponent <CustomGeometry>(); surfaceComponent.SetMaterial(_surfaceMaterial); surfaceComponent.BeginGeometry(0, PrimitiveType.TRIANGLE_LIST); // We initialize and add a single entry to the surface collider points list List <Vector2> surfacePoints = new List <Vector2>() { new Vector2(0, (float)_noise.Evaluate(startx * NoiseScaleX, 0) * NoiseScaleY ) }; // We translate the last surface extrusion point so it's local relative to the chunk we're creating _lastSurfaceExtrusion += Vector3.Left * Chunksize; // We loop all the segments in this chunk float incr = SurfaceSegmentSize; for (float x = 0; x < Chunksize - float.Epsilon * 8; x += incr) { // We store vars for the position for the current segment end point x position and for the y position of the 4 points float xEnd = x + incr; float tlY = SampleSurface(startx + x); float trY = SampleSurface(startx + xEnd); float blY = tlY + Chunkheight; float brY = trY + Chunkheight; // We create vectors that represent Vector3 bl = new Vector3(x, blY, -10); Vector3 tl = new Vector3(x, tlY, -10); Vector3 br = new Vector3(xEnd, brY, -10); Vector3 tr = new Vector3(xEnd, trY, -10); // We add the top right point to the surface points list (remember we added the first point in the list init) surfacePoints.Add(new Vector2(tr)); // We call the CreateDecor function passing the global position of the current segment end point and the segment angle CreateDecor(tr + Vector3.Right * startx, tl - tr); // We create the geometry of the surface (UV os oriented according to the surface) Vector2 startV = Vector2.UnitX * (x / Chunksize) * SurfaceRepeatPerChunk; Vector2 endV = Vector2.UnitX * (xEnd / Chunksize * SurfaceRepeatPerChunk); //bl surfaceComponent.DefineVertex(_lastSurfaceExtrusion); surfaceComponent.DefineTexCoord(startV); //tl surfaceComponent.DefineVertex(tl); surfaceComponent.DefineTexCoord(startV - Vector2.UnitY); //tr surfaceComponent.DefineVertex(tr); surfaceComponent.DefineTexCoord(-Vector2.UnitY + endV); //bl surfaceComponent.DefineVertex(_lastSurfaceExtrusion); surfaceComponent.DefineTexCoord(startV); //tr surfaceComponent.DefineVertex(tr); surfaceComponent.DefineTexCoord(-Vector2.UnitY + endV); //br - We store the last point to use for continuity _lastSurfaceExtrusion = tr + Quaternion.FromAxisAngle(Vector3.Back, 90) * Vector3.NormalizeFast(tr - tl); surfaceComponent.DefineVertex(_lastSurfaceExtrusion); surfaceComponent.DefineTexCoord(endV); // We create the geometry of the ground (UV is in world coordinates) //bl groundComponent.DefineVertex(bl); groundComponent.DefineTexCoord(new Vector2(bl / Chunksize)); //tl groundComponent.DefineVertex(tl); groundComponent.DefineTexCoord(new Vector2(tl / Chunksize)); //tr groundComponent.DefineVertex(tr); groundComponent.DefineTexCoord(new Vector2(tr / Chunksize)); //bl groundComponent.DefineVertex(bl); groundComponent.DefineTexCoord(new Vector2(bl / Chunksize)); //tr groundComponent.DefineVertex(tr); groundComponent.DefineTexCoord(new Vector2(tr / Chunksize)); //br groundComponent.DefineVertex(br); groundComponent.DefineTexCoord(new Vector2(br / Chunksize)); } // We commit the geometry data we just created surfaceComponent.Commit(); groundComponent.Commit(); // We create the collider component for the chunk surface CollisionChain2D surfaceCollider = node.CreateComponent <CollisionChain2D>(); surfaceCollider.SetLoop(false); surfaceCollider.SetFriction(1); surfaceCollider.SetVertexCount((uint)surfacePoints.Count + 1); _chunks.Add(surfaceCollider); // We add a small overlapping segment with a bit of negative offset in y so the wheel passes smoothly over chunk seams Vector2 smoother = new Vector2(-incr * .5f, (float)_noise.Evaluate((startx - incr * .5f) * NoiseScaleX, 0) * NoiseScaleY - .005f); surfaceCollider.SetVertex(0, smoother); // Finally, we set the vertex of the surface collider for (int c = 0; c < surfacePoints.Count; c++) { Vector2 surfacePoint = surfacePoints[c]; surfaceCollider.SetVertex((uint)c + 1, surfacePoint); } // A collider must have a rigid body to interact with other bodies, even if static which is the case node.CreateComponent <RigidBody2D>().SetBodyType(BodyType2D.BT_STATIC); }