Coulnt mesage this because its too long.
Sure! This code is about to be heavily modified though. but you may be able to pick somethign from it.
- The main issue with this code 1. moving RigidBodies is not easy as asetting a location 2. if teh crate flips.. it will bug out when the player uses it again. (beacuse of my clunky side detection code)
This is the crate class. it is abstract so we overload it for particular types of crates
Code:class Crate extends KActor abstract; // Set to true to make the object pushable. var(Crate) bool bPushable; // Set to true to make the object pullable. var(Crate) bool bPullable; var(Crate) CrateHandle CrateHandle0; // Handle offset. var(Crate) Vector HandleOffSet; // 2D Constraint. var RB_ConstraintActorSpawnable TwoDWorldConstraint; simulated event PostBeginPlay() { super.PostBeginPlay(); SetupWorldConstraint(); } function InitConstraint(UTPawn p) { // Do nothing here. Each subclass will create it's own constraint. } function SetupWorldConstraint() { //add a contraint to only allow the crate to move in a flat movement.. and not side to side. TwoDWorldConstraint = Spawn(class'RB_ConstraintActorSpawnable', , '', Location, rot(0,0,0)); TwoDWorldConstraint.ConstraintSetup.LinearYSetup.bLimited = 0; TwoDWorldConstraint.ConstraintSetup.LinearYSetup.LimitSize = 0; TwoDWorldConstraint.ConstraintSetup.LinearZSetup.bLimited = 0; TwoDWorldConstraint.ConstraintSetup.LinearZSetup.LimitSize = 0; TwoDWorldConstraint.ConstraintSetup.LinearXSetup.bLimited = 0; TwoDWorldConstraint.ConstraintSetup.LinearXSetup.LimitSize = 0; TwoDWorldConstraint.ConstraintSetup.bSwingLimited = true; TwoDWorldConstraint.ConstraintSetup.Swing1LimitAngle = 0; TwoDWorldConstraint.ConstraintSetup.Swing2LimitAngle = 0; TwoDWorldConstraint.ConstraintSetup.bTwistLimited = true; TwoDWorldConstraint.ConstraintSetup.TwistLimitAngle = 0; TwoDWorldConstraint.InitConstraint( self, None, '','',10000.0); `log("constraint initialized: "@TwoDWorldConstraint); } DefaultProperties { BlockRigidBody=true bBlockActors=true CollisionType=COLLIDE_BlockAll bCollideWorld=True bProjTarget=True bWakeOnLevelStart=true bCanStepUpOn=false bPushable=true bPullable=true HandleOffSet=(X=0,Y=64,Z=0) Begin Object Class=CrateHandle Name=CrateHandle0 LinearDamping=1.0 LinearStiffness=1000000.0 AngularDamping=1.0 AngularStiffness=1000000.0 LinearStiffnessScale3D=(X=1.0,Y=1.0,Z=1000.0) LinearDampingScale3D=(X=1.0,Y=1.0,Z=1000.0) End Object Components.Add(CrateHandle0) }
and here is the crate handle code
and in the player controller all you have to do is thisCode:/* CrateHandle.uc written by Emil Levy 2011 This class provides a method for temporarily attatching a specific rigid body actor to the player in such a way that the player seems to be pushing and/or pulling the actor. ver 1 - for prototyping purposes */ class CrateHandle extends RB_Handle; // global vars var bool bDebug; var Crate CurrentCrate; var float height; var Rotator rote; var vector offset; // Grab the crate... // Specifically attatch a RB_Handle like used with the physics gun. // Work out which side of the crate the player has attatched the handle to // and lock movement in that local axis. function Grab(Crate object, TraceHitInfo hitInfo, vector hitLocation, MyPawn p) { local Box playerBox, crateBox; local float playerHalfDim, crateHalfDim; local vector temp, newPawnLoc, hitNormal; local float xDir, yDir; local float extraOffset; local Rotator rotat; if (p.bIsBlocking) { return; } //safety check for a null object if (object == none) { `log("Tried to attach a null object to CrateHandle."); return; } //make sure the object is set in line with the world axis. // this is only for prototyping purposes. // -- FIX ME height = object.Location.z; object.SetCollision(false,false,false); object.StaticMeshComponent.SetRotation(rot(0,0,0)); object.SetCollision(true,true,true); rote = Object.StaticMeshComponent.Rotation; //find player halfdim p.GetComponentsBoundingBox(playerBox); object.GetComponentsBoundingBox(crateBox); playerHalfDim = (playerBox.Max - playerBox.Min).x / 2; crateHalfDim = (crateBox.Max - crateBox.Min).x / 2; //work out the player/handle offset if(p.IsA('MyPawnSmall')) { extraOffset = 6; } else { extraOffset = 30; } hitNormal = hitLocation - object.Location; xDir = hitNormal.x; yDir = hitNormal.y; //set the offset of the handle offset = vect(0.0, 0.0, 0.0); newPawnLoc = p.Location; offset.Z = object.Location.Z - p.Location.Z; //right if(xDir > yDir && xDir > 0 && xDir > (yDir * -1)) { //away `log("Right"); offset.x = extraOffset; newPawnLoc.x = object.Location.x + crateHalfDim + playerHalfDim + offset.x; newPawnLoc.y = object.Location.y; } //bottom else if(yDir < xDir && yDir < 0 && yDir < (xDir * -1)) { //in `log("Bottom"); offset.y = extraOffset; newPawnLoc.y = object.Location.y - crateHalfDim - playerHalfDim - offset.y; newPawnLoc.x = object.Location.x; } //top else if(yDir > xDir && yDir > 0 && yDir > (xDir * -1)) { //away `log("Top"); offset.y = extraOffset; newPawnLoc.y = object.Location.y + crateHalfDim + playerHalfDim + offset.y; newPawnLoc.x = object.Location.x; } //left else if(xDir < yDir && xDir < 0 && xDir < (yDir * -1)) { //in `log("left"); offset.x = extraOffset; newPawnLoc.x = object.Location.x - crateHalfDim - playerHalfDim - offset.x; newPawnLoc.y = object.Location.y; } else { return; } //move the player to the correct position. // disable collision object.SetCollision(false,false,false); p.SetLocation(newPawnLoc); temp = object.Location; temp.z = temp.z+1; rotat = rotator(object.location - p.location); rotat.Pitch = 1; p.SetRotation(rotat); //set the object in the right direction object.SetRotation(rot(0,0,0)); object.SetCollision(true,true,true); `log("Handle pos: "@self.GetHandleOffset(p)); // Init a new handle super.GrabComponent(hitInfo.HitComponent, hitInfo.BoneName, self.GetHandleOffset(p), false); //check that the handle was initiated correctly if (GrabbedComponent == none) { `log("CrateHandle wasn't able to grab Crate:" @ object); return; } CurrentCrate = object; // initiate the physics constraint and lock the crate to its axis. //CurrentCrate.InitConstraint(p); if (bDebug) `log("crate pos: "@CurrentCrate.Location); // change the players control state p.GoToState('pushing'); if (bDebug) `log("Handle_Location:" @ Location @ "HitActor_Location:" @ object.Location); // Set pawn variables p.bIsMovingAnObject = true; } //return true if the player has grabbed a crate function bool HasObject() { return CurrentCrate != none && GrabbedComponent != none; } // return the offset between the player and the cratehandle function Vector GetHandleOffset(MyPawn p) { local vector temp; temp = p.Location + offset; temp.Z = height +10; return temp; } //This method is to be called from a tick function to constantly update the position of the handle // and thereby the crate. This MUST be in a tick function to produce smooth results. function UpdateHandlePosition(MyPawn p) { if (HasObject()) { //rotate the object so it stays straight. CurrentCrate.StaticMeshComponent.SetRBRotation(rote); // Update handle position //GrabbedComponent.WakeRigidBody(GrabbedBoneName); super.SetLocation(self.GetHandleOffset(p)); if (bDebug) `log("Handle pos: "@self.GetHandleOffset(p)); if (bDebug) `log("crate pos updated: "@CurrentCrate.Location); } } //release the handle on the crate. function Release(MyPawn p) { // Release the object super.ReleaseComponent(); //terminate the object's physics constraints. CurrentCrate.TwoDWorldConstraint.TermConstraint(); CurrentCrate.SetLocation(CurrentCrate.Location); CurrentCrate = none; // Set pawn variables p.GoToState('walking'); p.bIsMovingAnObject = false; } DefaultProperties { TickGroup=TG_PreAsyncWork bDebug=true LinearDamping=1.0 LinearStiffness=1000.0 AngularDamping=1.0 AngularStiffness=1000.0 LinearStiffnessScale3D=(X=1.0,Y=1.0,Z=1.0) LinearDampingScale3D=(X=1.0,Y=1.0,Z=1.0) }
Code:function GrabHandle() { local vector loc, norm, end; local TraceHitInfo HitInfo; local Actor traceHit; local vector startPos; local Crate tempCrate; startPos = ThePlayer.GetPawnViewLocation(); end = ThePlayer.Location + normal(vector(ThePlayer.Rotation))*100; traceHit = worldinfo.trace(loc, norm, end, startPos, false,, HitInfo); //`log("rotation rate: "@ThePlayer.RotationRate); //ClientMessage("trace was fired from "$Location); if (traceHit == none) { //ClientMessage("Trace failed to register anything."); return; } //ClientMessage(traceHit); if(traceHit.IsA('Crate')) { tempCrate = Crate(traceHit); GrabbedCrate.Grab(tempCrate, HitInfo, loc, ThePlayer); } else { //ClientMessage("Not a crate"); return; } } function ReleaseHandle() { //call the release functionality in the grabbed object. GrabbedCrate.Release(ThePlayer); } function PlayerTick(float DeltaTime) { super.PlayerTick(DeltaTime); if(ThePlayer.bIsMovingAnObject) GrabbedCrate.UpdateHandlePosition(ThePlayer); ... }
Hope this helps you out a bit



Reply With Quote
as the code states this is concept proof level code (that never got updated).


Bookmarks