Announcement

Collapse

The Infinity Blade Forums Have Moved

We've launched brand new Infinity Blade forums with improved features and revamped layout. We've also included a complete archive of the previous posts. Come check out the new Infinity Blade forums.
See more
See less

Isometric Cam + WASD Movement + Aim at Mouse! (Alien Swarm style)

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

  • Isometric Cam + WASD Movement + Aim at Mouse! (Alien Swarm style)

    Hello,

    This is my first tutorial. I say tutorial, it's more of a "here's the code, with comments, have fun with it!" Hope it helps! This tutorial is going to assume you know the basics of programming and the basic classes (Pawn, GameInfo, Player Controller) of UDK. Also, it assumes you already have the folders setup for your game.

    End Result
    (Minus the cross-hair changing)


    Current Issues
    • No weapon mesh (Lost it somewhere when making the tutorial from my messy, WIP code)
    • Feign Death breaks it...


    Special Thanks
    • Roychr - For his Isometric Camera tutorial (here)
    • For the UDN!


    First up, let's get our GameInfo class. Nothing special goes on here, just assigning the default Pawn, HUD and PC. Also gives the player a LinkGun!

    MyGameInfo.uc
    Code:
    class MyGameInfo extends GameInfo;
    
    //Create inventory
    var array< class <Inventory> > DefaultInventory; 
    
    //Add default items to inventory of PlayerPawn
    function AddDefaultInventory( pawn PlayerPawn )
    {
        if(PlayerPawn.IsHumanControlled() )
        {
            PlayerPawn.CreateInventory(class'UTWeap_LinkGun',false);
        }
    }
    defaultproperties
    {
            bDelayedStart=false
    	HUDType=class'MouseInterfaceHUD'
    	PlayerControllerClass=class'MyPlayerController'
    	DefaultPawnClass=class'MyPawn'
    }
    That was easy! Now, onto our Pawn. Our Pawn will have the Camera functions built into it, rather than have a separate Camera Class.

    MyPawn.uc
    Code:
    class MyPawn extends UTPawn
    	config(Game)
    	notplaceable;
    
    //Camera Variables
    var float CamOffsetDistance; //distance to offset the camera from the player
    var int IsoCamAngle; //pitch angle of the camera
    
    //Makes the player mesh visable
    simulated event BecomeViewTarget( PlayerController PC )
    {
       local UTPlayerController UTPC;
    
       Super.BecomeViewTarget(PC);
    
       if (LocalPlayer(PC.Player) != None)
       {
          UTPC = MyPlayerController(PC);
          if (UTPC != None)
          {
             //set player controller to behind view and make mesh visible
             UTPC.SetBehindView(true);
             SetMeshVisibility(true);
             UTPC.bNoCrosshair = true;
          }
       }
    }
    // Uses the weapon height (if any), otherwise eye height, to define the start location of the projectile. Essentially, it causes the pawn to look straight ahead if you were in 1st person view.
    simulated function vector GetAimStartLocation()
    {
    	local Vector pawnAimLocation;
    	if (Weapon != none)
    	{
    		pawnAimLocation = Location + vect(0,0,1) * (Weapon.GetPhysicalFireStartLoc().Z - Location.Z); // just use upvector
    		return pawnAimLocation;
    	}
    	else
    	{
    		return GetPawnViewLocation(); // eye fallback
    	}
    }
    
    //Gives us our camera view.
    simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
    {
       out_CamLoc = Location;
       out_CamLoc.X -= Cos(IsoCamAngle * UnrRotToRad) * CamOffsetDistance;
       out_CamLoc.Z += Sin(IsoCamAngle * UnrRotToRad) * CamOffsetDistance;
    
       out_CamRot.Pitch = -1 * IsoCamAngle;
       out_CamRot.Yaw = 0;
       out_CamRot.Roll = 0;
    
       return true;
    }
    
    //Returns Aim Rotation
    simulated singular event Rotator GetBaseAimRotation()
    {
       local rotator POVRot, tempRot;
    
       tempRot = Rotation;
       tempRot.Pitch = 0;
       SetRotation(tempRot);
       POVRot = Rotation;
       POVRot.Pitch = 0;
    
       return POVRot;
    }   
    
    defaultproperties
    {  	
    	Begin Object Class=SkeletalMeshComponent Name=InitialSkeletalMesh
    		CastShadow=true
    		bCastDynamicShadow=true
    		bOwnerNoSee=false
    		LightEnvironment=MyLightEnvironment;
            BlockRigidBody=true;
            CollideActors=true;
            BlockZeroExtent=true;
    		PhysicsAsset=PhysicsAsset'CH_AnimCorrupt.Mesh.SK_C H_Corrupt_Male_Physics'
    		AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman _AimOffset'
    		AnimSets(1)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman _BaseMale'
    		AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_ Human'
    		SkeletalMesh=SkeletalMesh'CH_LIAM_Cathode.Mesh.SK_ CH_LIAM_Cathode'
    	End Object
    
    	Mesh=InitialSkeletalMesh;
    	Components.Add(InitialSkeletalMesh);
    	
       IsoCamAngle=8000 //6420 = 35.264 degrees Change this number for the camera angle
       CamOffsetDistance=512 //change this number for camera distance.
       GroundSpeed=256
    }
    Now for the PlayerController. This will have many functions relating to mouse input, as well as handle the pawn facing the mouse and WASD movement.

    MyPlayerController
    Code:
    class MyPlayerController extends UTPlayerController;
    
    // Mouse event enum
    enum EMouseEvent
    {
      LeftMouseButton,
      RightMouseButton,
      MiddleMouseButton,
      ScrollWheelUp,
      ScrollWheelDown,
    };
    var vector PlaneHitPos;
    var bool bRooted;
    var float PreviousSpeed;
    
    // Handle mouse inputs.
    function HandleMouseInput(EMouseEvent MouseEvent, EInputEvent InputEvent)
    {
      local MouseInterfaceHUD MouseInterfaceHUD;
    
      // Type cast to get our HUD
      MouseInterfaceHUD = MouseInterfaceHUD(myHUD);
    
      if (MouseInterfaceHUD != None)
      {
        // Detect what kind of input this is
        if (InputEvent == IE_Pressed)
        {
          // Handle pressed event
          switch (MouseEvent)
          {
            case LeftMouseButton:
         MouseInterfaceHUD.PendingLeftPressed = true;
         break;
    
       case RightMouseButton:
         MouseInterfaceHUD.PendingRightPressed = true;
         break;
    
       case MiddleMouseButton:
         MouseInterfaceHUD.PendingMiddlePressed = true;
         break;
    
       case ScrollWheelUp:
         MouseInterfaceHUD.PendingScrollUp = true;
         break;
    
       case ScrollWheelDown:
         MouseInterfaceHUD.PendingScrollDown = true;
         break;
    
       default:
         break;
          }
        }
        else if (InputEvent == IE_Released)
        {
          // Handle released event
          switch (MouseEvent)
          {
            case LeftMouseButton:
         MouseInterfaceHUD.PendingLeftReleased = true;
         break;
    
       case RightMouseButton:
         MouseInterfaceHUD.PendingRightReleased = true;
         break;
    
       case MiddleMouseButton:
         MouseInterfaceHUD.PendingMiddleReleased = true;
         break;
    
       default:
         break;
          }
        }
      }
    }
    
    // Hook used for the left and right mouse button when pressed
    exec function StartFire(optional byte FireModeNum)
    {
      HandleMouseInput((FireModeNum == 0) ? LeftMouseButton : RightMouseButton, IE_Pressed);
      Super.StartFire(FireModeNum);
    }
    
    // Hook used for the left and right mouse button when released
    exec function StopFire(optional byte FireModeNum)
    {
      HandleMouseInput((FireModeNum == 0) ? LeftMouseButton : RightMouseButton, IE_Released);
      Super.StopFire(FireModeNum);
    }
    
    // Called when the middle mouse button is pressed
    exec function MiddleMousePressed()
    {
      HandleMouseInput(MiddleMouseButton, IE_Pressed);
    }
    
    // Called when the middle mouse button is released
    exec function MiddleMouseReleased()
    {
      HandleMouseInput(MiddleMouseButton, IE_Released);
    }
    
    // Called when the middle mouse wheel is scrolled up
    exec function MiddleMouseScrollUp()
    {
      HandleMouseInput(ScrollWheelUp, IE_Pressed);
    }
    
    // Called when the middle mouse wheel is scrolled down
    exec function MiddleMouseScrollDown()
    {
      HandleMouseInput(ScrollWheelDown, IE_Pressed);
    }
    
    // Override this state because StartFire isn't called globally when in this function
    auto state PlayerWaiting
    {
      exec function StartFire(optional byte FireModeNum)
      {
        Global.StartFire(FireModeNum);
      }
    }
    
    //This is where the magic happens! This updates the pawn's rotation to face the mouse cursor!
    function UpdateRotation(float DeltaTime){
       local Rotator   targetRotation;
       local Vector    aimStartPos;
       local float     hitLength;
       local MouseInterfaceHUD   playerHud;
       local MyPawn  mypawn;
    
       if (self.Pawn != None)
       {
          mypawn = MyPawn(self.Pawn);
    			
            if (mypawn != none)
             {
                 aimStartPos = mypawn.GetAimStartLocation(); 
             }
             else
            {
                 aimStartPos = self.Pawn.GetPawnViewLocation();      
             }
    			
             playerHud = MouseInterfaceHUD(myHUD);
    
             // calc the player/world plane > deproj mouse ray intersection
             hitLength = -((vect(0,0,1) dot (playerHud.CachedMouseWorldOrigin - aimStartPos)) / (vect(0,0,1) dot playerHud.CachedMouseWorldDirection));
             PlaneHitPos = (playerHud.CachedMouseWorldOrigin + playerHud.CachedMouseWorldDirection * hitLength);
    		
             targetRotation = pawn.GetBaseAimRotation();
             targetRotation.Yaw = rotator(PlaneHitPos - aimStartPos).Yaw; // only update yaw
    
             Pawn.FaceRotation(targetRotation, DeltaTime);
             }
    	 else
    	 {
             super.UpdateRotation(DeltaTime);
    	 }
    }
    
    //The adjustments to this state cause WASD to function correctly. 
    state PlayerWalking
    {
    ignores SeePlayer, HearNoise, Bump;
    
       function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
       {
          if( Pawn == None )
          {
             return;
          }
    
          if (Role == ROLE_Authority)
          {
             // Update ViewPitch for remote clients
             Pawn.SetRemoteViewPitch( Rotation.Pitch );
          }
          //Forces WASD to work properly!
          Pawn.Acceleration.X = 1 * PlayerInput.aBaseY * DeltaTime * 100 * PlayerInput.MoveForwardSpeed;;
          Pawn.Acceleration.Y = 1 * PlayerInput.aStrafe * DeltaTime * 100 * PlayerInput.MoveForwardSpeed;
          Pawn.Acceleration.Z = 0;
    
          CheckJumpOrDuck();
       }
    }
    
    defaultproperties
    {   
      // Set the input class to the mouse interface player input
      InputClass=class'MouseInterfacePlayerInput'
    }
    Now, here comes the fun part. The Mouse Interface. Info on this can be found here: http://udn.epicgames.com/Three/Devel...Interface.html That page can explain it better than I can, so read up on that!

    MouseInterfaceGfx.uc
    Code:
    class MouseInterfaceGFx extends GFxMoviePlayer;
    
    var MouseInterfaceHUD MouseInterfaceHUD;
    
    function Init(optional LocalPlayer LocalPlayer)
    {
    	// Initialize the ScaleForm movie
    	Super.Init(LocalPlayer);
    
    	Start();
        Advance(0);
    }
    
    event UpdateMousePosition(float X, float Y)
    {
    	local MouseInterfacePlayerInput MouseInterfacePlayerInput;
    
    	if (MouseInterfaceHUD != None && MouseInterfaceHUD.PlayerOwner != None)
    	{
    		MouseInterfacePlayerInput = MouseInterfacePlayerInput(MouseInterfaceHUD.PlayerOwner.PlayerInput);
    
    		if (MouseInterfacePlayerInput != None)
    		{
    			MouseInterfacePlayerInput.SetMousePosition(X, Y);
    		}
    	}
    }
    
    defaultproperties
    {    
        bDisplayWithHudOff=false
        TimingMode=TM_Game
        bPauseGameWhileActive=false
    }
    MouseInterfaceHUD.uc
    Code:
    class MouseInterfaceHUD extends HUD;
    
    // The texture which represents the cursor on the screen
    var Texture2D CursorTexture;
    // The color of the cursor
    var const Color CursorColor;
    // Pending left mouse button pressed event
    var bool PendingLeftPressed;
    // Pending left mouse button released event
    var bool PendingLeftReleased;
    // Pending right mouse button pressed event
    var bool PendingRightPressed;
    // Pending right mouse button released event
    var bool PendingRightReleased;
    // Pending middle mouse button pressed event
    var bool PendingMiddlePressed;
    // Pending middle mouse button released event
    var bool PendingMiddleReleased;
    // Pending mouse wheel scroll up event
    var bool PendingScrollUp;
    // Pending mouse wheel scroll down event
    var bool PendingScrollDown;
    // Cached mouse world origin
    var Vector CachedMouseWorldOrigin;
    // Cached mouse world direction
    var Vector CachedMouseWorldDirection;
    // Last mouse interaction interface
    var MouseInterfaceInteractionInterface LastMouseInteractionInterface;
    // Use ScaleForm?
    var bool UsingScaleForm;
    // Scaleform mouse movie
    var MouseInterfaceGFx MouseInterfaceGFx;
    
    simulated event PostBeginPlay()
    {
      Super.PostBeginPlay();
    
      // If we are using ScaleForm, then create the ScaleForm movie
      if (UsingScaleForm)
      {
        MouseInterfaceGFx = new () class'MouseInterfaceGFx';
        if (MouseInterfaceGFx != None)
        {
          MouseInterfaceGFx.MouseInterfaceHUD = Self;
          MouseInterfaceGFx.SetTimingMode(TM_Game);
    
          MouseInterfaceGFx.Init(class'Engine'.static.GetEngine().GamePlayers[MouseInterfaceGFx.LocalPlayerOwnerIndex]);
        }
      }
    }
    
    simulated event Destroyed()
    {
      Super.Destroyed();
      
      // If the ScaleForm movie exists, then destroy it
      if (MouseInterfaceGFx != None)
      {
        MouseInterfaceGFx.Close(true);
        MouseInterfaceGFx = None;
      }
    }
    
    function PreCalcValues()
    {
      Super.PreCalcValues();
    
      // If the ScaleForm movie exists, then reset it's viewport, scale mode and alignment to match the
      // screen resolution
      if (MouseInterfaceGFx != None)
      {
        MouseInterfaceGFx.SetViewport(0, 0, SizeX, SizeY);
        MouseInterfaceGFx.SetViewScaleMode(SM_NoScale);
        MouseInterfaceGFx.SetAlignment(Align_TopLeft);  
      }
    }
    
    /*simulated function SwitchCursorTexture(Texture2D Cursor)
    {
    local MouseInterfacePlayerInput MouseInterfacePlayerInput;
     // Ensure that we aren't using ScaleForm and that we have a valid cursor
      if (!UsingScaleForm && CursorTexture != None)
      {
        // Ensure that we have a valid PlayerOwner
        if (PlayerOwner != None)
        {
          // If we're not using scale form and we have a valid cursor texture, render it
          if (MouseInterfacePlayerInput != None)
          {
            Canvas.DrawTile(Cursor, CursorTexture.SizeX, CursorTexture.SizeY, 0.f, 0.f, CursorTexture.SizeX, CursorTexture.SizeY,, true);
          }
        }
      }
    }       */
    event PostRender()
    {
      local MouseInterfacePlayerInput MouseInterfacePlayerInput;
      local MouseInterfaceInteractionInterface MouseInteractionInterface;
      local Vector HitLocation, HitNormal;
    
      Super.PostRender();
    
      // Ensure that we aren't using ScaleForm and that we have a valid cursor
      if (!UsingScaleForm && CursorTexture != None)
      {
        // Ensure that we have a valid PlayerOwner
        if (PlayerOwner != None)
        {
          // Cast to get the MouseInterfacePlayerInput
          MouseInterfacePlayerInput = MouseInterfacePlayerInput(PlayerOwner.PlayerInput)  ;
    
          // If we're not using scale form and we have a valid cursor texture, render it
          if (MouseInterfacePlayerInput != None)
          {
            // Set the canvas position to the mouse position
            Canvas.SetPos(MouseInterfacePlayerInput.MousePosition.X, MouseInterfacePlayerInput.MousePosition.Y);
            // Set the cursor color
            Canvas.DrawColor = CursorColor;
            // Draw the texture on the screen
            Canvas.DrawTile(CursorTexture, CursorTexture.SizeX, CursorTexture.SizeY, 0.f, 0.f, CursorTexture.SizeX, CursorTexture.SizeY,, true);
          }
        }
      }
    
      // Get the current mouse interaction interface
      MouseInteractionInterface = GetMouseActor(HitLocation, HitNormal);
    
      // Handle mouse over and mouse out
      // Did we previously had a mouse interaction interface?
      if (LastMouseInteractionInterface != None)
      {
        // If the last mouse interaction interface differs to the current mouse interaction
        if (LastMouseInteractionInterface != MouseInteractionInterface)
        {
          // Call the mouse out function
          LastMouseInteractionInterface.MouseOut(CachedMouseWorldOrigin, CachedMouseWorldDirection);
          // Assign the new mouse interaction interface
          LastMouseInteractionInterface = MouseInteractionInterface; 
    
          // If the last mouse interaction interface is not none
          if (LastMouseInteractionInterface != None)
          {
            // Call the mouse over function
            LastMouseInteractionInterface.MouseOver(CachedMouseWorldOrigin, CachedMouseWorldDirection); // Call mouse over
          }
        }
      }
      else if (MouseInteractionInterface != None)
      {
        // Assign the new mouse interaction interface
        LastMouseInteractionInterface = MouseInteractionInterface; 
        // Call the mouse over function
        LastMouseInteractionInterface.MouseOver(CachedMouseWorldOrigin, CachedMouseWorldDirection); 
      }
    
      if (LastMouseInteractionInterface != None)
      {
        // Handle left mouse button
        if (PendingLeftPressed)
        {
          if (PendingLeftReleased)
          {
            // This is a left click, so discard
            PendingLeftPressed = false;
            PendingLeftReleased = false;
          }
          else
          {
            // Left is pressed
            PendingLeftPressed = false;
            LastMouseInteractionInterface.MouseLeftPressed(CachedMouseWorldOrigin, CachedMouseWorldDirection, HitLocation, HitNormal);
          }
        }
        else if (PendingLeftReleased)
        {
          // Left is released
          PendingLeftReleased = false;
          LastMouseInteractionInterface.MouseLeftReleased(CachedMouseWorldOrigin, CachedMouseWorldDirection);
        }
    
        // Handle right mouse button
        if (PendingRightPressed)
        {
          if (PendingRightReleased)
          {
            // This is a right click, so discard
            PendingRightPressed = false;
            PendingRightReleased = false;
          }
          else
          {
            // Right is pressed
            PendingRightPressed = false;
            LastMouseInteractionInterface.MouseRightPressed(CachedMouseWorldOrigin, CachedMouseWorldDirection, HitLocation, HitNormal);
          }
        }
        else if (PendingRightReleased)
        {
          // Right is released
          PendingRightReleased = false;
          LastMouseInteractionInterface.MouseRightReleased(CachedMouseWorldOrigin, CachedMouseWorldDirection);
        }
    
        // Handle middle mouse button
        if (PendingMiddlePressed)
        {
          if (PendingMiddleReleased)
          {
            // This is a middle click, so discard 
            PendingMiddlePressed = false;
            PendingMiddleReleased = false;
          }
          else
          {
            // Middle is pressed
            PendingMiddlePressed = false;
            LastMouseInteractionInterface.MouseMiddlePressed(CachedMouseWorldOrigin, CachedMouseWorldDirection, HitLocation, HitNormal);
          }
        }
        else if (PendingMiddleReleased)
        {
          PendingMiddleReleased = false;
          LastMouseInteractionInterface.MouseMiddleReleased(CachedMouseWorldOrigin, CachedMouseWorldDirection);
        }
    
        // Handle middle mouse button scroll up
        if (PendingScrollUp)
        {
          PendingScrollUp = false;
          LastMouseInteractionInterface.MouseScrollUp(CachedMouseWorldOrigin, CachedMouseWorldDirection);
        }
    
        // Handle middle mouse button scroll down
        if (PendingScrollDown)
        {
          PendingScrollDown = false;
          LastMouseInteractionInterface.MouseScrollDown(CachedMouseWorldOrigin, CachedMouseWorldDirection);
        }
      }
    }
    
    function MouseInterfaceInteractionInterface GetMouseActor(optional out Vector HitLocation, optional out Vector HitNormal)
    {
      local MouseInterfaceInteractionInterface MouseInteractionInterface;
      local MouseInterfacePlayerInput MouseInterfacePlayerInput;
      local Vector2D MousePosition;
      local Actor HitActor;
    
      // Ensure that we have a valid canvas and player owner
      if (Canvas == None || PlayerOwner == None)
      {
        return None;
      }
    
      // Type cast to get the new player input
      MouseInterfacePlayerInput = MouseInterfacePlayerInput(PlayerOwner.PlayerInput)  ;
    
      // Ensure that the player input is valid
      if (MouseInterfacePlayerInput == None)
      {
        return None;
      }
    
      // We stored the mouse position as an IntPoint, but it's needed as a Vector2D
      MousePosition.X = MouseInterfacePlayerInput.MousePosition.X;
      MousePosition.Y = MouseInterfacePlayerInput.MousePosition.Y;
      // Deproject the mouse position and store it in the cached vectors
      Canvas.DeProject(MousePosition, CachedMouseWorldOrigin, CachedMouseWorldDirection);
    
      // Perform a trace actor interator. An interator is used so that we get the top most mouse interaction
      // interface. This covers cases when other traceable objects (such as static meshes) are above mouse
      // interaction interfaces.
      ForEach TraceActors(class'Actor', HitActor, HitLocation, HitNormal, CachedMouseWorldOrigin + CachedMouseWorldDirection * 65536.f, CachedMouseWorldOrigin,,, TRACEFLAG_Bullet)
      {
        // Type cast to see if the HitActor implements that mouse interaction interface
        MouseInteractionInterface = MouseInterfaceInteractionInterface(HitActor);
        if (MouseInteractionInterface != None)
        {
          return MouseInteractionInterface;
        }
      }
    
      return None;
    }
    
    function Vector GetMouseWorldLocation()
    {
      local MouseInterfacePlayerInput MouseInterfacePlayerInput;
      local Vector2D MousePosition;
      local Vector MouseWorldOrigin, MouseWorldDirection, HitLocation, HitNormal;
    
      // Ensure that we have a valid canvas and player owner
      if (Canvas == None || PlayerOwner == None)
      {
        return Vect(0, 0, 0);
      }
    
      // Type cast to get the new player input
      MouseInterfacePlayerInput = MouseInterfacePlayerInput(PlayerOwner.PlayerInput)  ;
    
      // Ensure that the player input is valid
      if (MouseInterfacePlayerInput == None)
      {
        return Vect(0, 0, 0);
      }
    
      // We stored the mouse position as an IntPoint, but it's needed as a Vector2D
      MousePosition.X = MouseInterfacePlayerInput.MousePosition.X;
      MousePosition.Y = MouseInterfacePlayerInput.MousePosition.Y;
      // Deproject the mouse position and store it in the cached vectors
      Canvas.DeProject(MousePosition, MouseWorldOrigin, MouseWorldDirection);
    
      // Perform a trace to get the actual mouse world location.
      Trace(HitLocation, HitNormal, MouseWorldOrigin + MouseWorldDirection * 65536.f, MouseWorldOrigin , true,,, TRACEFLAG_Bullet);
      return HitLocation;
    }
    
    defaultproperties
    {
      // Set to false if you wish to use Unreal's player input to retrieve the mouse coordinates
      UsingScaleForm=false
      CursorColor=(R=255,G=255,B=255,A=255)
      CursorTexture=Texture2D'EngineResources.Cursors.Arrow'
    }
    MouseInterfaceInteractionInterface.uc
    Code:
    interface MouseInterfaceInteractionInterface;
    
    // Called when the left mouse button is pressed
    function MouseLeftPressed(Vector MouseWorldOrigin, Vector MouseWorldDirection, Vector HitLocation, Vector HitNormal);
    
    // Called when the left mouse button is released
    function MouseLeftReleased(Vector MouseWorldOrigin, Vector MouseWorldDirection);
    
    // Called when the right mouse button is pressed
    function MouseRightPressed(Vector MouseWorldOrigin, Vector MouseWorldDirection, Vector HitLocation, Vector HitNormal);
    
    // Called when the right mouse button is released
    function MouseRightReleased(Vector MouseWorldOrigin, Vector MouseWorldDirection);
    
    // Called when the middle mouse button is pressed
    function MouseMiddlePressed(Vector MouseWorldOrigin, Vector MouseWorldDirection, Vector HitLocation, Vector HitNormal);
    
    // Called when the middle mouse button is released
    function MouseMiddleReleased(Vector MouseWorldOrigin, Vector MouseWorldDirection);
    
    // Called when the middle mouse button is scrolled up
    function MouseScrollUp(Vector MouseWorldOrigin, Vector MouseWorldDirection);
    
    // Called when the middle mouse button is scrolled down
    function MouseScrollDown(Vector MouseWorldOrigin, Vector MouseWorldDirection);
    
    // Called when the mouse is moved over the actor
    function MouseOver(Vector MouseWorldOrigin, Vector MouseWorldDirection);
    
    // Called when the mouse is moved out from the actor (when it was previously over it)
    function MouseOut(Vector MouseWorldOrigin, Vector MouseWorldDirection);
    
    // Returns the hit location of the mouse trace
    function Vector GetHitLocation();
    
    // Returns the hit normal of the mouse trace
    function Vector GetHitNormal();
    
    // Returns the mouse world origin calculated by the deprojection within the canvas
    function Vector GetMouseWorldOrigin();
    
    // Returns the mouse world direction calculated by the deprojection within the canvas
    function Vector GetMouseWorldDirection();
    MouseInterfacePlayerInput.uc
    Code:
    class MouseInterfacePlayerInput extends PlayerInput;
    
    var PrivateWrite IntPoint MousePosition;
    
    event PlayerInput(float DeltaTime)
    {
    	local MouseInterfaceHUD MouseInterfaceHUD;
    
    	// Handle mouse movement
    	// Check that we have the appropriate HUD class
    	MouseInterfaceHUD = MouseInterfaceHUD(MyHUD);
    	if (MouseInterfaceHUD != None)
    	{
    		if (!MouseInterfaceHUD.UsingScaleForm)
    		{
    			// If we are not using ScaleForm, then read the mouse input directly
    			// Add the aMouseX to the mouse position and clamp it within the viewport width
    			MousePosition.X = Clamp(MousePosition.X + aMouseX, 0, MouseInterfaceHUD.SizeX);
    			// Add the aMouseY to the mouse position and clamp it within the viewport height
    			MousePosition.Y = Clamp(MousePosition.Y - aMouseY, 0, MouseInterfaceHUD.SizeY);
    		}
    	}
    
    	Super.PlayerInput(DeltaTime);
    }
    
    function SetMousePosition(int X, int Y)
    {
    	if (MyHUD != None)
    	{
    		MousePosition.X = Clamp(X, 0, MyHUD.SizeX);
    		MousePosition.Y = Clamp(Y, 0, MyHUD.SizeY);
    	}
    }
    
    defaultproperties
    {
    }

  • #2
    Very cool! Too bad I'm creating an fps ! :P

    Comment


    • #3
      Feel free to add any comments for improving the code. I'm pretty new myself and learning as I go, so the code may not be the best. Hope this helps point people to the right direction though!

      Comment


      • #4
        +1 Internets to you mate, I've been banging my head against the wall trying to create this from scratch.

        One little note though, found several spelling errors, mystical space breaks all over the place:
        • MyGameInfo.uc, row 11
        • MyPawn.uc, rows 81-85
        • MouseInterfaceHUD.uc, rows 47, 116, 136, 144, 153, 171, 178, 194, 201, 217, 223, 230 and 323
        • MouseInterfaceGfx, row 20


        Get these fixed and this is a perfect tutorial. Once again, thank you

        Comment


        • #5
          Thanks heaps man, this is exactly what I needed to get my feet off the ground making a top down/isometric shooter.

          Comment


          • #6
            Originally posted by LordJebe View Post
            +1 Internets to you mate, I've been banging my head against the wall trying to create this from scratch.

            One little note though, found several spelling errors, mystical space breaks all over the place:
            • MyGameInfo.uc, row 11
            • MyPawn.uc, rows 81-85
            • MouseInterfaceHUD.uc, rows 47, 116, 136, 144, 153, 171, 178, 194, 201, 217, 223, 230 and 323
            • MouseInterfaceGfx, row 20


            Get these fixed and this is a perfect tutorial. Once again, thank you
            Very late reply, and no idea how they snuck in there...maybe when copy+pasting it added them. Anyway, updated it. Should still be working on the newest UDK.

            Comment


            • #7
              Test it please with shock rifle, i wonder, will you get same issue i've got.

              Anyway, thanks for mouse tracing.

              Comment


              • #8
                In you GFxMovie class, you declare your MouseInterfaceHUD variable, and even used it a lot, but nothing was assigned to it.

                UPD. How to fix a little offset of shooting? I mean, to make pawn shoot directly at cursor instead of just looking on it.

                Comment


                • #9
                  Originally posted by lentinant View Post
                  In you GFxMovie class, you declare your MouseInterfaceHUD variable, and even used it a lot, but nothing was assigned to it.

                  UPD. How to fix a little offset of shooting? I mean, to make pawn shoot directly at cursor instead of just looking on it.
                  The offset is from the weapon, as far as I know. Something like "Aim Offset" in the default properties. As for declaring the variable, it's probably because I have used the reference in my project, but didn't remove it when I stripped down the code for this tutorial. I'm sure any decent programmer can remove what isn't needed.

                  Comment


                  • #10
                    Originally posted by Zaiteria View Post
                    The offset is from the weapon, as far as I know. Something like "Aim Offset" in the default properties.
                    According to my experience, weapon offset desires, where beams or projectiles will be spawned. It is a slightly dsfferent problem, i think. Here is scheme of shooting from top-down view, as i see it.

                    Sorry for mad skillz, though. So, i think, we have offset, because weapon is not aimed on cursor itself.

                    Comment


                    • #11
                      Nice one. Thanks. Does anyone know how to change this code so it playable on mobile?

                      Comment


                      • #12
                        Originally posted by lentinant View Post
                        According to my experience, weapon offset desires, where beams or projectiles will be spawned. It is a slightly dsfferent problem, i think. Here is scheme of shooting from top-down view, as i see it.

                        Sorry for mad skillz, though. So, i think, we have offset, because weapon is not aimed on cursor itself.
                        I believe the function you want to edit is "simulated function vector GetAimStartLocation()" in the Pawn class. Although that'll make it spawn at the character's head in order to reach the middle of the crosshair. Play around with it, I don't have time at the moment to test anything though, sorry.

                        Comment


                        • #13
                          Very nice. Just wondering, is there a way to get this to work if you extend the gametype from UTDeathmatch instead of GameInfo? I'm working on a robotron esque game right now, but my game extends from UTDeathmatch. Sorry if this sounds like a noobish question. I'm still very new to UDKscript.

                          Comment


                          • #14
                            Awesome, awesome little tut. I've followed along and everything came out great with some minor fixes to the spacing of the Skeletal Mesh. The one issue I'm having is that the LinkGun mesh is invisible (and I think the firing offset is a little off). Has anyone run into this? Trying to track down the heart of the issue.

                            Again thanks for sharing!

                            Comment


                            • #15
                              Very nice , It reminds me the first army man series system

                              Comment

                              Working...
                              X