Announcement

Collapse
No announcement yet.

Procedural(ish) roads in UDK

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

  • replied
    Get rid of spawning individual collisions and attach static mesh components to actors with imported simplified collision created in 3d package.
    Listen to Spoof.
    He knows a great deal that most others do not.

    Leave a comment:


  • replied
    Error!!

    Originally posted by cargarage22 View Post
    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.
    [0001.67] Init: Version: 10900
    [0001.67] Init: Epic Internal: 0
    [0001.67] Init: Compiled (32-bit): Feb 18 2013 19:22:39
    [0001.67] Init: Command line:
    [0001.67] Init: Base directory: C:\Users\Mr.Technology\Desktop\UDK\UDK-2013-02\Binaries\Win32\
    [0001.67] Init: Character set: Unicode
    [0001.67] Log: Executing Class UnrealEd.MakeCommandlet
    [0002.13] --------------------Core - Release--------------------
    [0002.17] --------------------Engine - Release--------------------
    [0002.20] Analyzing...
    [0003.34] C:\Users\Mr.Technology\Desktop\UDK\UDK-2013-02\Development\Src\Engine\Classes\splineActor_coll idable.uc(41) : Error, Unexpected end of file at end of
    Class
    [0003.59] Compile aborted due to errors.
    [0003.63]
    [0003.63] Warning/Error Summary
    [0003.63] ---------------------
    [0003.63] C:\Users\Mr.Technology\Desktop\UDK\UDK-2013-02\Development\Src\Engine\Classes\splineActor_coll idable.uc(41) : Error, Unexpected end of file at end of
    Class
    [0003.63]
    [0003.63] Failure - 1 error(s), 0 warning(s)
    [0003.63]
    Execution of commandlet took: 1.95 seconds

    Please help!!

    Leave a comment:


  • replied
    Originally posted by TorQueMoD View Post
    Not knocking what you've done Online/Offworld, its absolutely brilliant, but I just think the collisions will use far too many resources once you get a few dozen roads in place.
    You are unfortunately quite right

    Hope to play with this a bit more in the future and find some way to optimize it, but my job has me insanely busy at the moment so I don't know when that's going to happen...

    Leave a comment:


  • replied
    Thanks a lot for the script @online|offworld,
    well I looking down tutorial over tutorial and I found how it works, importing the scripts in.
    But somehow it doesnt work in the "splineActor_collidable.uc"
    When i update my outdated scripts, Udk gives me an error, telling me :
    unrecognized type 'ColliderMesh' .
    I even tried to edit your script, but i dont know where the error is.
    Could

    Leave a comment:


  • replied
    SplineLoftActor_Collidable dosent work collisions
    !

    Leave a comment:


  • replied
    Originally posted by Chosker View Post
    perpoly collision on meshes doesn't work...
    Maybe you meant perpoly collision on SPLINE meshes doesn't work. Cause perpoly on static meshes does indeed work.
    Also this method although really cool, is definitely going to be incredibly system intensive with the number of collision meshes generated. You'd be better off at this point to use static mesh pieces for your roads.
    Not knocking what you've done Online/Offworld, its absolutely brilliant, but I just think the collisions will use far too many resources once you get a few dozen roads in place.

    Leave a comment:


  • replied
    Originally posted by Spoof View Post
    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.
    Got that working (SplineLoftActor_SMC is an extended static mesh component with absolute translation). I think I'll try the other method you mention later.
    Code:
    	SMC = new(self) class'SplineLoftActor_SMC';
    	SMC.SetTranslation(argLocation + vect(0,0,40));
    	SMC.SetRotation(Rotator(argRotation));
    	SMC.SetScale3D(tVect); //Needs to match a pre-cached physics scale to work properly
    	AttachComponent(SMC);
    	SMC.InitRBPhys();

    Here's my full Collidable actor, which auto adjusts the collision mesh (with pre-cached physics scales) to reduce the # of components. Still need to implement handling for curves and implement collision meshes that can go across multiple straight splines:
    Code:
    class SplineLoftActor_Collidable extends SplineLoftActor;
    var vector loc,rot;
    var int collisionSpacing;
    var int collisionRemaining;
    var int collisionTaken,j;
    var int MaxSpace;
    var SplineLoftActor_SMC SMC_Init;
    
    enum WCollisionSizeEnum
    {
    	e25,
    	e50,
        e100,
    	e200,
    	e300,
    	e400,
    	e600,
    	e800,
    };
    var WCollisionSizeEnum tSize;
    
    event PostBeginPlay(){
    	super.PostBeginPlay();
    	CreateCollision();
    }
    
    function CreateCollision(){
    	local float splineLength;
    	local int i;
    
    
    	if(Connections.Length > 0){
    		splineLength = Connections[0].SplineComponent.GetSplineLength();
    		collisionRemaining=splineLength;
    
    		if(Connections[0].SplineComponent.SplineCurviness > 0.99){
    			i=0;
    			while(collisionRemaining > MaxSpace){
    				if(collisionRemaining > 800){
    					tSize = e800;
    					collisionTaken = 800;
    				}else if(collisionRemaining > 600){
    					tSize = e600;
    					collisionTaken = 600;
    				}else if(collisionRemaining > 400){
    					tSize = e400;
    					collisionTaken = 400;
    				}else if(collisionRemaining > 300){
    					tSize = e300;
    					collisionTaken = 300;
    				}else if(collisionRemaining > 200){
    					tSize = e200;
    					collisionTaken = 200;
    				}else if(collisionRemaining > 100){
    					tSize = e100;
    					collisionTaken = 100;
    				}else if(collisionRemaining > 50){
    					tSize = e50;
    					collisionTaken = 50;
    				}else if(collisionRemaining > 25){
    					tSize = e25;
    					collisionTaken = 25;
    				}
    
    				i+=collisionTaken*0.5f;
    				loc = Connections[0].SplineComponent.GetLocationAtDistanceAlongSpline(i);
    				rot = Connections[0].SplineComponent.GetTangentAtDistanceAlongSpline(i);
    
    		
    				spawnColliderInstance(loc,rot);
    		
    				
    				j+=1;
    				//`log(loc);
    				//`log("Created "$j$": "$collisionTaken$" at "$i);
    		
    				
    				collisionRemaining-=collisionTaken;
    				i+=collisionTaken*0.5f;
    				if(collisionRemaining <= MaxSpace){
    					//`log("Finished with collisionRemaining: "$collisionRemaining$" and "$i$"/"$splineLength);
    				}
    			}   
    
    			//`log("collisionRemaining: "$collisionRemaining);
    		}
    	}
    
    	for(i=0;i<SplineMeshComps.Length;i++){
    		SplineMeshComps[i].SetBlockRigidBody(false);
    	}
    }
    
    function spawnColliderInstance(Vector argLocation, Vector argRotation){
    	local SplineLoftActor_SMC SMC;
    	local Vector tVect;
    
    	tVect.X = 0.25f;
    	tVect.Y = 2.5f;
    	tVect.Z = 1.f;
    
    	switch(tSize){
    		case e25:
    			tVect.X = 0.25f;
    			break;
    		case e50:
    			tVect.X = 0.5f;
    			break;
    		case e100:
    			tVect.X = 1.0f;
    			break;
    		case e200:
    			tVect.X = 2.0f;
    			break;
    		case e300:
    			tVect.X = 3.0f;
    			break;
    		case e400:
    			tVect.X = 4.0f;
    			break;
    		case e600:
    			tVect.X = 6.0f;
    			break;
    		case e800:
    			tVect.X = 8.0f;
    			break;
    		default:
    			tVect.X = 1.0f;
    			break;
    	}
    
    	SMC = new(self) class'SplineLoftActor_SMC';
    	SMC.SetTranslation(argLocation + vect(0,0,40));
    	SMC.SetRotation(Rotator(argRotation));
    	SMC.SetScale3D(tVect);
    	AttachComponent(SMC);
    	SMC.InitRBPhys();
    }
    
    defaultproperties
    {
    	bEdShouldSnap=true
    	bStatic=true
    	bMovable=false
    	bCollideActors=false
    	bBlockActors=false
    	bWorldGeometry=false
    	bGameRelevant=true
    	bCollideWhenPlacing=false
    	CollisionType=COLLIDE_BlockAll
    	
    	BlockRigidBody=false
    	bCollideAsEncroacher = true
    
    	tSize = e200
    	j=0
    	MaxSpace=50
    	bAlwaysEncroachCheck=true
    }
    The SMC class. The static mesh is an upside down pyramid imported at 100x100 , so it scales nicely. :
    Code:
    class SplineLoftActor_SMC extends StaticMeshComponent;
    
    DefaultProperties
    {
    	// Various physics related items need to be ticked pre physics update
    	TickGroup=TG_PreAsyncWork
    
    	WireframeColor=(R=0,G=255,B=255,A=255)
    	bAcceptsStaticDecals=TRUE
    	bAcceptsDecals=TRUE
    	bOverrideLightMapResolution=TRUE
    	OverriddenLightMapResolution=0
    	bOverrideLightMapRes=FALSE
    	OverriddenLightMapRes=64
    	bUsePrecomputedShadows=FALSE
    	SubDivisionStepSize=32
    	bUseSubDivisions=TRUE
    	bForceStaticDecals=FALSE
    	bCanHighlightSelectedSections=false
    	StreamingDistanceMultiplier=1.0
    
    	RBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE,Vehicle=TRUE,Untitled4=TRUE,Untitled3=true,Pawn=TRUE)
    	RBChannel=RBCC_GameplayPhysics
    
    
    	StaticMesh=StaticMesh'WarsawTest.roads.RoadCollision'
    
    	HiddenGame=false
    	Translation=(X=0.0,Y=0.0,Z=0.0)
    	Scale3D=(X=1.0,Y=2.5,Z=1.0)
    
    	AbsoluteRotation=true
    	AbsoluteScale=true
    	AbsoluteTranslation=true
    	
    	BlockRigidBody=true
    	BlockNonZeroExtent=True
        BlockZeroExtent=true
        BlockActors=true
    	CollideActors=true
    	bDisableAllRigidBody=false
    	AlwaysCheckCollision=false
    	bBlockFootPlacement=false
    }

    Leave a comment:


  • replied
    Sweet! Thanks guys

    Leave a comment:


  • replied
    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.

    Leave a comment:


  • replied
    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.

    Leave a comment:


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

    Leave a comment:


  • replied
    Sorry, my bad.
    I thought the post was referring to meshes in general.

    Leave a comment:


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

    Leave a comment:


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

    Leave a comment:


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

    Leave a comment:

Working...
X