How to make aiming system for FPS game?

Hello,

I have been trying to make a aiming in system where the right mouse is held and the player starts looking down the sight of the gun. I really have no code to show because I don’t know where to begin. The only thing that is going on is that the gun is looking at the center of the screen. Other than that and shooting, there is nothing else to show. I don’t want only hip fire. So in just about any FPS, CoD, Battlefield, and SOOO many more games, you have the ability to look down your sights of any gun. That is what I want to do. Should I make an animation somehow (I have no arms yet, if I even decide to add arms)? I think using Vector3.Lerp could possibly work, but I am not sure. Now keep in mind since my gun is slightly rotated, it will need to rotate and look straight forward while aiming in since the Ray system I have uses transform.forward to make a ray. Any suggestions of doing this sort of thing? And is “Scripting” even the right category for this sort of question? If not, I am sorry, I am just lost when it comes to coding aiming in and inventory systems.

I think it would help you to write out everything it would do:
-lerp between camera positions
-lerp between zooms with feild of view
-lerp between poses
-lerp between accuracy floats
-change movement speed
-change camera rotation speed
-change rigid body rotation speed
-and if need be, add a draw to texture for the scope

Get inspired by for example UFPS.

1 Like

See my attachment

Have 2 cameras one is the main camera the other is the aim camera.
Make sure near clipping plains is 0.01 on both cameras.
Line up aim cam with the iron sight (or acog, red dot w/e) and makea script that switches between the 2 cameras on right mouse down.

Thank you all for your replies, they actually direct me toward somewhere and I appreciate that.

@Nubz i know exactly what you are saying here, but would there a way to do this while playing an animation where the gun literally moves to a point and it is where the camera is aiming down the sights? Becuase if I do it your way, there will be nothing happening but transform and if I decide to make the game multiplayer, that would look weird.

EDIT:
And by “switching” the cameras, do you mean move the main camera to the aim in position and the hip fire position? And the aim in position would just be the “Aim” camera gameobject’s position. Hip fire position would be the main camera’s initial position.

Morning Vlentful,
have you had a look at Mikes Multiplayer Xmas FPS shooter on the live training archive?
http://unity3d.com/learn/tutorials/modules/intermediate/live-training-archive/merry-fragmas-multiplayer-fps

theres some good tips on there for aiming/running animations for the guns etc.

heres his published content on dropbox to test (not sure how long it will be there for tho)
https://dl.dropboxusercontent.com/u/6116499/FPS_webbuild/FPS_webbuild.html

1 Like

Wow, thank you OboShape. Unity tutorials are usually the best tutorials. I am going to watch that now!

Yes I’ve heard of it being anmiation based I guess that would eliminate the extra camera.
I think all it is is calling the animation instead not sure though since the model I have isn’t animated which is part of why I use all the camera tricks and stuff.

Just never watched this because I don’t have the animations and it’s in UnityScript

https://www.youtube.com/watch?v=TvUoo1oWcJQ

By switching cameras I mean switching cameras.
The aim camera can be a pita to line up properly also I have found.
Here is the script I use maybe it will help you understand what I am getting at better.

using UnityEngine;
using System.Collections;

public class ScopeCam : MonoBehaviour
{

    public Camera aimCam;
    public Camera mainCam;
 

    void Update ()
    {
        if (Input.GetMouseButtonDown(1))
        {
            aimCam.enabled = true;
            mainCam.enabled = false;
        }
        if (Input.GetMouseButtonUp(1))
        {
            aimCam.enabled = false;
            mainCam.enabled = true;
        }
    }
}

Pretty simple actually all it does is switch the camera for you.

2 Likes

Thank you everyone for helping out. I just finished watching that “Merry Fragmas” Unity Offical Live Stream Archive and now, I know how to aim in by using animation. I recommend everyone to watch that video, he uses 2 cameras and animation. Thank you everyone and I finally know how to aim in now!

EDIT:
Thank you, Nubz, for clarifiying that a little better. I was pretty sure that was what you meant but I was not 100% positive that was what you meant.

I would recommend changing the fov for iron sights and using a second camera for scopes. And a third camera that is disabled and manually calls render to stop the gun from clipping through nearby objects :stuck_out_tongue:

Did you say use a disabled camera? What would that do? And I am using a camera for the clipping part. The guy in the Unity tutorial showed how to do that.

If you disable the camera, it will only render when you call thatCamera.Render();

It’s just an optimization thing. If you are using Render, it’s likely to force it to render last so the object appears on top of everything else. If you leave the camera enabled, it might render before you call Render and when you call Render. It just cuts down on that :slight_smile:

Thats pretty much what i already have expect I’m not using my FOV script at all right now.
I thought the scope style looked better on the red dot sight I have.

Also using a camera for the gun so it looks like its not going through the walls.

I never knew that. You learn something new everyday I guess. Thank you!

I have another question. Really almost a preference question though. I am wondering, how do you guys do your raycast shooting? I have a shoot point inside my gun and do “transform.forward” for the direction of the Ray. But I think a problem could happen from this. Like if the gun actually is going through a wall even though there is correct clipping, and the player shoots, the player could kill someone through the wall. I think having a shoot point somewhere else would work better, but what do you guys do? I am just curious about this…

I usually raycast from the camera because if you introduce any kind of animation to your player body, the gun barrel becomes an unreliable piece to shoot from. You can still do muzzle flashes and stuff from the gun, and you can offset the ray from the camera head to simulate hip fire inaccuracy.

Typically when you go to iron sight / scope aim, the gun forward and camera forward are nearly the same ray anyway.

Not my script but:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AIMDOWNSIGHTS : MonoBehaviour
{
public Vector3 aimDownScope;
public Vector3 hipFire;
//something

//something bout fps
void Update (){
if (Input.GetMouseButton (1)) {
transform.localPosition = Vector3.Slerp(transform.localPosition,hipFire, 10 * Time.deltaTime);
}
if (Input.GetMouseButtonUp (1)) {
transform.localPosition = aimDownScope;
}
}
}

1 Like

I also recommend checking out this tutorial as it specifically goes into doing nice scope effects.

1 Like

Thank you very much. I have code similar to this but it was too messy.

thx this helped me i changed it alot so it works perfectly

I have a question? I already have the shooting system script but I want to only shoot when I’m aiming how can I write in the script for that?

ing System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using StarterAssets;
using UnityEngine.InputSystem;
public class ThirdPersonShooterController : MonoBehaviour
{
[SerializeField] private CinemachineVirtualCamera aimVirtualCamera;
[SerializeField] private float normalSensitivity;
[SerializeField] private float aimSensitivity;
[SerializeField] private LayerMask aimColliderLayerMask = new LayerMask();
[SerializeField] private Transform debugTransform;
[SerializeField] private Transform Bullet;
[SerializeField] private Transform Bullet1;
[SerializeField] private Transform spawnBulletPosition;
[SerializeField] private Transform spawnBulletPosition1;
private ThirdPersonController thirdPersonController;
private StarterAssetsInputs starterAssetsInputs;
private Animator animator;
private void Awake()
{
thirdPersonController = GetComponent();
starterAssetsInputs = GetComponent();
animator = GetComponent();
}
private void Update()
{
Vector3 mouseWorldPosition = Vector3.zero;
Vector2 screenCenterPoint = new Vector2(Screen.width / 2f, Screen.height / 2f);
Ray ray = Camera.main.ScreenPointToRay(screenCenterPoint);
if (Physics.Raycast(ray, out RaycastHit raycastHit, 999f, aimColliderLayerMask))
{
debugTransform.position = raycastHit.point;
mouseWorldPosition = raycastHit.point;
}
if (starterAssetsInputs.aim)
{
aimVirtualCamera.gameObject.SetActive(true);
thirdPersonController.SetSensitivity(aimSensitivity);
thirdPersonController.SetRotateOnMove(false);
animator.SetLayerWeight(1, Mathf.Lerp(animator.GetLayerWeight(1), 1f, Time.deltaTime * 10f));
Vector3 worldAimTarget = mouseWorldPosition;
worldAimTarget.y = transform.position.y;
Vector3 aimDirection = (worldAimTarget - transform.position).normalized;
transform.forward = Vector3.Lerp(transform.forward, aimDirection, Time.deltaTime * 20f);
}
else
{
aimVirtualCamera.gameObject.SetActive(false);
thirdPersonController.SetSensitivity(normalSensitivity);
thirdPersonController.SetRotateOnMove(true);
animator.SetLayerWeight(1, Mathf.Lerp(animator.GetLayerWeight(1), 0f, Time.deltaTime * 10f));
}
if (starterAssetsInputs.shoot)
{
Vector3 aimDir = (mouseWorldPosition - spawnBulletPosition.position).normalized;
Instantiate(Bullet, spawnBulletPosition.position, Quaternion.LookRotation(aimDir, Vector3.up));
starterAssetsInputs.shoot = false;
}
if (starterAssetsInputs.shoot1)
{
Vector3 aimDir = (mouseWorldPosition - spawnBulletPosition1.position).normalized;
Instantiate(Bullet1, spawnBulletPosition1.position, Quaternion.LookRotation(aimDir, Vector3.up));
starterAssetsInputs.shoot1 = false;
}

}
}