Announcement

Collapse
No announcement yet.

Procedural(ish) roads in UDK

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Procedural(ish) roads in UDK

    Hi Everyone,

    One of the things that always annoyed me about UDK was the absence of a decent road tool. Of course, we do have spline lofts but their default settings make them seem glitchy and unusable, and worse, they have no collision. So even if you get them to laid out in your scene, when you try and run on them you just fall through them

    So two issues there:
    1. unglitching them - turns out there's a couple simple tweaks to their settings that sort them out (once you've figured out why they were going mental)
    2. no collision! - for this I had to learn a bit of unrealscripting (big shout out to FTC for his fantastic tutes on working with splineLoftActors)

    Here's a video explaining the above and showing my custom splineLoftActor working with collision (p.s. I'm cloning the spline nodes by holding Alt when I move them) :



    And here are the scripts (if you don't know where to put these you need to go and find a tute on the basics of using custom scripts in UDK) :

    splineActor_collidable.uc
    Code:
    class splineActor_collidable extends SplineLoftActor;
    
    var array<colliderMesh> colliders;
    var vector loc,rot;
    var () Vector collisionScale;
    var () int collisionSpacing;
    
    event PostBeginPlay()
    {
    	local float splineLength;
    	local int i;
    	
    	splineLength = self.Connections[0].SplineComponent.GetSplineLength();
    	
    	for(i=0; i<splineLength; i+=collisionSpacing) {
    		loc = Connections[0].SplineComponent.GetLocationAtDistanceAlongSpline(  i);
    		rot = Connections[0].SplineComponent.GetTangentAtDistanceAlongSpline(i  );
    		spawnColliderInstance(loc,rot,collisionScale);
    	}
    }
    
    function spawnColliderInstance(Vector argLocation, Vector argRotation, Vector argScale)
    {
    	local colliderMesh spawnedCollider;
    	local staticMeshComponent spawnedColliderMeshCompononent;
    	
    	spawnedCollider = Spawn(class'colliderMesh', self, , argLocation, Rotator(argRotation),,true);
    	spawnedCollider.setDrawScale3D(argScale);
    	
    	spawnedColliderMeshCompononent = new () class'StaticMeshComponent';
    	if(spawnedColliderMeshCompononent != None)
    	{
    		spawnedCollider.AttachComponent(spawnedColliderMeshCompononent);
    	}
    }
    
    defaultproperties
    {
    }
    colliderMesh.uc
    Code:
    class colliderMesh extends StaticMeshActor
    	placeable;
    
    DefaultProperties
    {
    	bCollideActors=true
    	bBlockActors=true
    	
    	Begin Object Class=StaticMeshComponent Name=TouchProxy
            StaticMesh=StaticMesh'UN_SimpleMeshes.TexPropCube_Dup'
    		BlockNonZeroExtent=true
            BlockZeroExtent=false
            BlockActors=true		
    		HiddenGame=true
    		Translation=(X=0.0,Y=0.0,Z=0.0)
            CollideActors=true
            Scale3D=(X=1,Y=1,Z=1)
        End Object
    	
    	CollisionComponent=TouchProxy
        Components.Add(TouchProxy)
    	
    	DrawScale = 1
    	bNoDelete = false
    	bStatic = false
    	bMovable = true
    }

    #2
    I never tried this myself, but have you tried using perpoly collision on the mesh? Maybe that will work.

    Comment


      #3
      perpoly collision on meshes doesn't work

      offworld: sorry I ever doubted you, and thanks for sharing the code!

      Comment


        #4
        Nice! Thanks!

        Comment


          #5
          Sweet! Thanks, man!

          Comment


            #6
            one small problem : you can't drive the scorpion on it

            I had a look at the scorpions code and properties but haven't been able to make much sense of it...

            Any suggestions or advice gratefully accepted

            Comment


              #7
              Why not write an editor brush to place the road easier

              Comment


                #8
                Ummm... Not sure you can unrealscript a custom brush and not sure why you would for spline lofts?

                Comment


                  #9
                  Originally posted by Chosker View Post
                  perpoly collision on meshes doesn't work
                  Since when.

                  Comment


                    #10
                    Originally posted by DGUnreal View Post
                    Since when.
                    since you try to use them with the spline loft actor

                    Comment


                      #11
                      Sorry, my bad.
                      I thought the post was referring to meshes in general.

                      Comment


                        #12
                        That is awesome, and it was enjoyable to watch. I need to start messing with this spline loft stuff!

                        Comment


                          #13
                          Thanks for the code online|offworld.

                          To get vehicles properly working with your method of collision on the spline actors:

                          In the colliderMesh class, set the Scale3D line to your desired scale (same as your tutorial here):
                          Code:
                              Begin Object Class=StaticMeshComponent Name=TouchProxy
                                  StaticMesh=StaticMesh'WarsawTest.TexPropCube_Dup'
                          	BlockNonZeroExtent=true
                                  BlockZeroExtent=false
                                  BlockActors=true
                          	CollideActors=true
                          	HiddenGame=true
                          	Translation=(X=0.0,Y=0.0,Z=0.0)
                                  Scale3D=(X=0.2,Y=1,Z=0.1)
                              End Object
                          Next, add this to the bottom of postbeginplay of splineActor_collidable.
                          Code:
                              for(i=0;i<SplineMeshComps.Length;i++){
                          	SplineMeshComps[i].SetBlockRigidBody(false);
                              }
                          Now, set a Pre Cached Phys Scale on the TexPropCube_Dup (recommend copying this to one of your custom packages) to your desired scale (in your tutorial case, 0.2,1.0,0.1). Note this isn't necessarily required, but it removes the "Cooking Convex For Actor:" log error.

                          What was happening was UDK didn't rescale the physics asset to what the new scale was, so the rigid body collision was happening on the original size box still. Also there's some weird stuff going on with SplineMeshComps but setting them all to not block rigid works.

                          Separately, you can disable the collision on the splineActor_collidable to make it easier to see the collision when debugging.

                          Thanks for the code, it saved a lot of time.

                          Comment


                            #14
                            You could optimise this by creating StaticMeshComponents and adding them to the loft actor, instead of spawning unique actors for each collider. This would also simplify realtime updates if you wanted a swaying/bouncing rope bridge.

                            A completely alternative, outside-the-box solution is to create a single planar collision to accompany the vehicle itself. This collision component is updated to position beneath the vehicle, offset and angled to the nearest spline point (think of a blob shadow that changes orientation to match the spline tangent). It's a lot more work and has some technical hurdles (calculating closest relative spline position, falling off edges, you'd need one for each wheel for accuracy) but the benefit is it has the potential to perfectly mimic the curvature of the spline.

                            Comment


                              #15
                              Sweet! Thanks guys

                              Comment

                              Working...
                              X