Announcement

Collapse
No announcement yet.

Custom Physics gun with bindable Push&Pull functions

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

    Custom Physics gun with bindable Push&Pull functions

    Hello,

    I looked around for something like this but didn't find anything useful so tried to make my own and it works
    so decided to share the class for those who need it

    Edited UTWeap_PhysicsGun
    - Removed Poke Function Disabled.
    - Added a variable DefaultHoldDistance to force a minimum HoldDistance between the grabbed object and the player Pawn.
    - Added Push and Pull functions to Push/Pull the grabbed object.

    UPDATE:
    - Added a Max push distance (set to HoldDistanceMax you can set your own look for "function PushTimer()" and edit the IF statement)


    here is a demo video


    The class Code:
    Code:
    /**
     * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
     */
    class MyGame_Physicsgun extends UTWeapon
    	HideDropDown;
    
    var()				float			WeaponImpulse;
    var()				float			HoldDistanceMin;
    var()				float			HoldDistanceMax;
    var()				float			ThrowImpulse;
    var()				float			ChangeHoldDistanceIncrement;
    
    var					RB_Handle		PhysicsGrabber;
    var					float			HoldDistance;
    var					Quat			HoldOrientation;
    
    
    simulated function PostBeginPlay()
    {
    	Super.PostbeginPlay();
     
    }
    
    /**
     * This function is called from the pawn when the visibility of the weapon changes
     */
    simulated function ChangeVisibility(bool bIsVisible)
    {
    	Super.ChangeVisibility(bIsVisible);
    }
    
    simulated function StartFire(byte FireModeNum)
    {
    	local vector					StartShot, EndShot; //PokeDir; 
    	local vector					HitLocation, HitNormal, Extent;
    	local actor						HitActor;
    	local float						HitDistance;
    	local Quat						PawnQuat, InvPawnQuat, ActorQuat;
    	local TraceHitInfo				HitInfo;
    	local SkeletalMeshComponent		SkelComp;
    	local Rotator					Aim;
    	local PhysAnimTestActor			PATActor;
    	local StaticMeshComponent HitComponent;
    	local KActorFromStatic NewKActor;
    
    	if ( Role < ROLE_Authority )
    		return;
    
    	// Do ray check and grab actor
    	StartShot	= Instigator.GetWeaponStartTraceLocation();
    	Aim			= GetAdjustedAim( StartShot );
    	EndShot		= StartShot + (10000.0 * Vector(Aim));
    	Extent		= vect(0,0,0);
    	HitActor	= Trace(HitLocation, HitNormal, EndShot, StartShot, True, Extent, HitInfo, TRACEFLAG_Bullet);
    	HitDistance = VSize(HitLocation - StartShot);
    
    	HitComponent = StaticMeshComponent(HitInfo.HitComponent);
    	if ( (HitComponent != None) ) 
    	{
    		if(HitInfo.PhysMaterial != none)
    		{
    			if(HitInfo.PhysMaterial.ImpactSound != none)
    			{
    				PlaySound(HitInfo.PhysMaterial.ImpactSound,,,,HitLocation);
    			}
    
    			if(HitInfo.PhysMaterial.ImpactEffect != none)
    			{
    				WorldInfo.MyEmitterPool.SpawnEmitter(HitInfo.PhysMaterial.ImpactEffect, HitLocation, rotator(HitNormal), none);
    			}
    		}
    
    		if( HitComponent.CanBecomeDynamic() )
    		{
    			NewKActor = class'KActorFromStatic'.Static.MakeDynamic(HitComponent);
    			if ( NewKActor != None )
    			{
    				HitActor = NewKActor;
    			}
    		}
    	}
    
    	// POKE
    	if(FireModeNum == 0)
    	{ 
    /**	 // Uncomment to enable the poke function
    
    		PokeDir = Vector(Aim);
    
    		if ( PhysicsGrabber.GrabbedComponent == None )
    		{
    			// `log("HitActor:"@HitActor@"Hit Bone:"@HitInfo.BoneName);
    			if( HitActor != None &&
    				HitActor != WorldInfo &&
    				HitInfo.HitComponent != None )
    			{
    				PATActor = PhysAnimTestActor(HitActor);
    				if(PATActor != None)
    				{
    					if( !PATActor.PrePokeActor(PokeDir) )
    					{
    						return;
    					}
    				}
    
    				HitInfo.HitComponent.AddImpulse(PokeDir * WeaponImpulse, HitLocation, HitInfo.BoneName);
    			}
    		}
    		else
    		{
    			PhysicsGrabber.GrabbedComponent.AddImpulse(PokeDir * ThrowImpulse, , PhysicsGrabber.GrabbedBoneName);
    			PhysicsGrabber.ReleaseComponent();
    		}
    	}
    	// GRAB
    	else
    	{
    		*/
    
    		if( HitActor != None &&
    			HitActor != WorldInfo &&
    			HitInfo.HitComponent != None &&
    			HitDistance > HoldDistanceMin &&
    			HitDistance < HoldDistanceMax )
    		{   
    			PATActor = PhysAnimTestActor(HitActor);
    			if(PATActor != None)
    			{
    				if( !PATActor.PreGrab() )
    				{
    					return;
    				}
    			}
    
    			// If grabbing a bone of a skeletal mesh, dont constrain orientation.
    			SkelComp = SkeletalMeshComponent(HitInfo.HitComponent);
    			PhysicsGrabber.GrabComponent(HitInfo.HitComponent, HitInfo.BoneName, HitLocation, (SkelComp == None) && (PlayerController(Instigator.Controller).bRun==0));
    
    			// If we succesfully grabbed something, store some details.
    			if (PhysicsGrabber.GrabbedComponent != None)
    			{
    				HoldDistance	= HitDistance;
    				PawnQuat		= QuatFromRotator( Rotation );
    				InvPawnQuat		= QuatInvert( PawnQuat );
    
    				if ( HitInfo.BoneName != '' )
    				{
    					ActorQuat = SkelComp.GetBoneQuaternion(HitInfo.BoneName);
    				}
    				else
    				{
    					ActorQuat = QuatFromRotator( PhysicsGrabber.GrabbedComponent.Owner.Rotation );
    				}
    
    				HoldOrientation = QuatProduct(InvPawnQuat, ActorQuat);
    			}
    		}
    	}
    
    	Super.StartFire( FireModeNum );
    }
    
    simulated function StopFire(byte FireModeNum)
    {
    	local PhysAnimTestActor	PATActor;
    
    	if ( PhysicsGrabber.GrabbedComponent != None )
    	{
    		PATActor = PhysAnimTestActor(PhysicsGrabber.GrabbedComponent.Owner);
    		if(PATActor != None)
    		{
    			PATActor.EndGrab();
    		}
    
    		PhysicsGrabber.ReleaseComponent();
    	}
    
    	Super.StopFire( FireModeNum );
    }
    
    simulated function bool DoOverridePrevWeapon()
    {
    	HoldDistance += ChangeHoldDistanceIncrement;
    	HoldDistance = FMin(HoldDistance, HoldDistanceMax);
    	return false;
    }
    
    simulated function bool DoOverrideNextWeapon()
    {
    	HoldDistance -= ChangeHoldDistanceIncrement;
    	HoldDistance = FMax(HoldDistance, HoldDistanceMin);
    	return false;
    }
    
    simulated function Tick( float DeltaTime )
    {
    	local vector	NewHandlePos, StartLoc;
    	local Quat		PawnQuat, NewHandleOrientation;
    	local Rotator	Aim;
    	local int    DefaultHoldDistance;
    
     	if ( PhysicsGrabber.GrabbedComponent == None )
     	{
     		return;
     	}
    
    	PhysicsGrabber.GrabbedComponent.WakeRigidBody( PhysicsGrabber.GrabbedBoneName );
    
    	// Update handle position on grabbed actor.
    	if( Instigator != None )
    	{ 
    		DefaultHoldDistance = 96;
    		StartLoc		= Instigator.GetWeaponStartTraceLocation();
    		Aim				= GetAdjustedAim( StartLoc );
    		// The Default/minimum distence between the grabbed object and the pawn
    		
    	    if(HoldDistance<DefaultHoldDistance){
    	    	HoldDistance=DefaultHoldDistance;
    	    }
    		NewHandlePos	= StartLoc + (HoldDistance * Vector(Aim));
    		PhysicsGrabber.SetLocation( NewHandlePos );
    
    		// Update handle orientation on grabbed actor.
    		PawnQuat				= QuatFromRotator( Rotation );
    		NewHandleOrientation	= QuatProduct(PawnQuat, HoldOrientation);
    		PhysicsGrabber.SetOrientation( NewHandleOrientation );
    	}
    }
    
    /**
     * Consumes some of the ammo
     */
    function ConsumeAmmo( byte FireModeNum )
    {
    	// dont consume ammo
    }
    
    /**
     * The Push and Pull funchtions
     */
    exec function PushHold()
    {
    	SetTimer(0.005,True,'PushTimer');
    	
    	`log("Push Hold ");
    	 
    }
    
    exec function PushReleased()
    {
    	ClearTimer('PushTimer');
    	`log("Push Release ");
    	 
    }
    
    exec function PullHold()
    {
    	SetTimer(0.005,True,'PullTimer');
    	`log("Pull Hold");
    }
    
    exec function PullReleased()
    {
    	ClearTimer('PullTimer');
    	`log("Push Release ");
    	 
    }
    
    
    function PushTimer()
    {
    	if(HoldDistance<HoldDistanceMax){
    	HoldDistance+=4;
    	}
    }
    
    function PullTimer()
    {
    	HoldDistance-=4;
    }
    
    defaultproperties
    {
    	HoldDistanceMin=0.0
    	HoldDistanceMax=750.0
    	WeaponImpulse=2000.0
    	ThrowImpulse=100.0
    	ChangeHoldDistanceIncrement=50.0
    
    	Begin Object Class=RB_Handle Name=RB_Handle0
    		LinearDamping=1.0
    		LinearStiffness=50.0
    		AngularDamping=1.0
    		AngularStiffness=50.0
    	End Object
    	Components.Add(RB_Handle0)
    	PhysicsGrabber=RB_Handle0
    
    	WeaponColor=(R=255,G=255,B=128,A=255)
    	FireInterval(0)=+1.0
    	FireInterval(1)=+1.0
    	PlayerViewOffset=(X=0.0,Y=7.0,Z=-9.0)
    
    	Begin Object class=AnimNodeSequence Name=MeshSequenceA
    	End Object
    
    	WeaponFireTypes(0)=EWFT_Custom
    	WeaponFireTypes(1)=EWFT_Projectile
    
    	FireOffset=(X=16,Y=10)
    
    	AIRating=+0.75
    	CurrentRating=+0.75
    	bInstantHit=false
    	bSplashJump=false
    	bRecommendSplashDamage=false
    	bSniping=false
    	ShouldFireOnRelease(0)=0
    	ShouldFireOnRelease(1)=0
    	bCanThrow=false
    
    	InventoryGroup=666
    	GroupWeight=0.5
    
    	AmmoCount=99
    	LockerAmmoCount=99
    	MaxAmmoCount=99
    
    	bExportMenuData=false
    }


    Key Binding:
    Code:
    .Bindings=(Name="GBA_PushAway",Command="PushHold | OnRelease PushReleased") 
    .Bindings=(Name="X" ,Command="GBA_PushAway")
    .Bindings=(Name="GBA_PullBack",Command="PullHold | OnRelease PullReleased") 
    .Bindings=(Name="Z" ,Command="GBA_PullBack")
    I'am new to UDK so there may be some wrong methods in the code please correct me if you find any

    TODO:
    - Add a Rotate function to rotate the grabbed object Left/Right and UP/Down

    Thanks

    #2
    This looks pretty cool! Thanks, Ahmed90!

    Comment


      #3
      You're welcome

      just did a little update

      - Added a Max push distance (set to HoldDistanceMax you can set your own look for "function PushTimer()" and edit the IF statement)

      Comment


        #4
        Just a little question did you tried to set the stiffness higher? so that it actually really just moves the way you're moving? and stops lagging behind?

        Cause thats something i tried, and im getting really weird physics behaviors and sometimes my object goes through walls aswell.

        Comment


          #5
          just tried it yep it gives weird physics
          i believe its collision problem if we can make it somehow stop moving when it touches a collision object

          //edit

          after some research it looks like its not physics gun issue its a collision issue
          check it yourself in the static mesh editor > body setup > "Enable Continuous Collision Detection" read the description (tool tip)

          Comment


            #6
            Hi, everybody....i'm new to unrealscript and udk.
            I found this script very useful...i always wanted to play with a physics gun in "Half-Life 2" style.
            I managed to implement a function to move the grabbed objects upwards, but sadly (most likely due to poor implementation) the object falls to the ground as soon as i release the key.
            Could somebody help me to implement a "grab object - and - move it up" script that doesn't let the object fall as soon as the key is released? Also...some pointers to how to rotate the object in midair would be useful. Thanks in Advance.

            Comment


              #7
              Originally posted by cybernewbie View Post
              Hi, everybody....i'm new to unrealscript and udk.
              I found this script very useful...i always wanted to play with a physics gun in "Half-Life 2" style.
              I managed to implement a function to move the grabbed objects upwards, but sadly (most likely due to poor implementation) the object falls to the ground as soon as i release the key.
              Could somebody help me to implement a "grab object - and - move it up" script that doesn't let the object fall as soon as the key is released? Also...some pointers to how to rotate the object in midair would be useful. Thanks in Advance.
              This is very simple.
              Physics controls how the object falls correct?
              So in your script, under the desired conditions you just need to change the physic state with a function

              Also getting the location and rotation vector variables of actors is easy, so is updating them
              Controlling the rotation could be done via exec function and keybind or by text input field via UI

              Now you have enough to get started.
              good luck!

              Comment

              Working...
              X