ETeeskiTutorials Scripts up to FPS1.23

Hey guys, here are all the scripts up until episode FPS1.23. Also, I will have at the end of this thread post a link to download the version of FPS1 that I’ve been using for the tutorials.
If you want to learn to make a first person shooter from scratch with all your own code, check out my tutorials on youtube. Here’s a link to the first episode:
FPS1.1 The Overview. Unity3D FPS Game Design Tutorial.

Download the zip file of FPS1.23 (Same file you see me using in the tutorials):
817321–30259–$FPS1.23.zip (3.73 MB)

BulletScript.js

var maxDist : float = 1000000000;
var decalHitWall : GameObject;
var floatInFrontOfWall : float = 0.00001;

function Update () 
{
	var hit : RaycastHit;
	if (Physics.Raycast(transform.position, transform.forward, hit, maxDist))
	{
		if (decalHitWall  hit.transform.tag == "Level Parts")
			Instantiate(decalHitWall, hit.point + (hit.normal * floatInFrontOfWall), Quaternion.LookRotation(hit.normal));
	}
	Destroy(gameObject);
}

GunScript.js

@HideInInspector
var playerTransform : Transform;
@HideInInspector
var playerMovementScript : PlayerMovementScript;

@HideInInspector
var cameraObject : GameObject;
@HideInInspector
var targetXRotation : float;
@HideInInspector
var targetYRotation : float;
@HideInInspector
var targetXRotationV : float;
@HideInInspector
var targetYRotationV : float;

var rotateSpeed : float = 0.3;

var holdHeight : float = -0.5;
var holdSide : float = 0.5;
var racioHipHold : float = 1;
var hipToAimSpeed : float = 0.1;
@HideInInspector
var racioHipHoldV : float;

var aimRacio : float = 0.4;

var zoomAngle : float = 30;

var fireSpeed : float = 15;
@HideInInspector
var waitTilNextFire : float = 0;
var bullet : GameObject;
var bulletSpawn : GameObject;

var shootAngleRandomizationAiming : float = 5;
var shootAngleRandomizationNotAiming : float = 15;

var recoilAmount : float = 0.5;
var recoilRecoverTime : float = 0.2;
@HideInInspector
var currentRecoilZPos : float;
@HideInInspector
var currentRecoilZPosV : float;

var bulletSound : GameObject;
var muzzelFlash : GameObject;

var gunbobAmountX : float = 0.5;
var gunbobAmountY : float = 0.5;
var currentGunbobX : float;
var currentGunbobY : float;

function Awake ()
{
	countToThrow = -1;
	playerTransform = GameObject.FindWithTag("Player").transform;
	playerMovementScript = GameObject.FindWithTag("Player").GetComponent(PlayerMovementScript);
	cameraObject = GameObject.FindWithTag("MainCamera");
}

function LateUpdate () 
{
if (beingHeld)
{
	rigidbody.useGravity = false;
	outsideBox.GetComponent(Collider).enabled = false;
	
	currentGunbobX = Mathf.Sin(cameraObject.GetComponent(MouseLookScript).headbobStepCounter) * gunbobAmountX * racioHipHold;
	currentGunbobY = Mathf.Cos(cameraObject.GetComponent(MouseLookScript).headbobStepCounter * 2) * gunbobAmountY * -1 * racioHipHold;
	
	var holdMuzzelFlash : GameObject;
	var holdSound : GameObject;
	if (Input.GetButton("Fire1"))
	{
		if (waitTilNextFire <= 0)
		{
			if (bullet)
				Instantiate(bullet,bulletSpawn.transform.position, bulletSpawn.transform.rotation);
			if (bulletSound)
				holdSound = Instantiate(bulletSound, bulletSpawn.transform.position, bulletSpawn.transform.rotation);
			if (muzzelFlash)
				holdMuzzelFlash = Instantiate(muzzelFlash, bulletSpawn.transform.position, bulletSpawn.transform.rotation);
			targetXRotation += (Random.value - 0.5) * Mathf.Lerp(shootAngleRandomizationAiming, shootAngleRandomizationNotAiming, racioHipHold);
			targetYRotation += (Random.value - 0.5) * Mathf.Lerp(shootAngleRandomizationAiming, shootAngleRandomizationNotAiming, racioHipHold);
			currentRecoilZPos -= recoilAmount;
			waitTilNextFire = 1;
		}
	}
	waitTilNextFire -= Time.deltaTime * fireSpeed;

	if (holdSound)
		holdSound.transform.parent = transform;
	if (holdMuzzelFlash)
		holdMuzzelFlash.transform.parent = transform;

	currentRecoilZPos = Mathf.SmoothDamp( currentRecoilZPos, 0, currentRecoilZPosV, recoilRecoverTime);

	cameraObject.GetComponent(MouseLookScript).currentTargetCameraAngle = zoomAngle;

	if (Input.GetButton("Fire2")){
		cameraObject.GetComponent(MouseLookScript).currentAimRacio = aimRacio;
		racioHipHold = Mathf.SmoothDamp(racioHipHold, 0, racioHipHoldV, hipToAimSpeed);}
	if (Input.GetButton("Fire2") == false){
		cameraObject.GetComponent(MouseLookScript).currentAimRacio = 1;
		racioHipHold = Mathf.SmoothDamp(racioHipHold, 1, racioHipHoldV, hipToAimSpeed);}

	transform.position = cameraObject.transform.position + (Quaternion.Euler(0,targetYRotation,0) * Vector3(holdSide * racioHipHold + currentGunbobX, holdHeight * racioHipHold + currentGunbobY, 0) + Quaternion.Euler(targetXRotation, targetYRotation, 0) * Vector3(0,0,currentRecoilZPos));
	
	targetXRotation = Mathf.SmoothDamp( targetXRotation, cameraObject.GetComponent(MouseLookScript).xRotation, targetXRotationV, rotateSpeed);
	targetYRotation = Mathf.SmoothDamp( targetYRotation, cameraObject.GetComponent(MouseLookScript).yRotation, targetYRotationV, rotateSpeed);
	
	transform.rotation = Quaternion.Euler(targetXRotation, targetYRotation, 0);
}
if (!beingHeld)
{
	rigidbody.useGravity = true;
	outsideBox.GetComponent(Collider).enabled = true;
	
	countToThrow -= 1;
	if (countToThrow == 0)
		rigidbody.AddRelativeForce(0, playerMovementScript.throwGunUpForce, playerMovementScript.throwGunForwardForce);
	
	if (Vector3.Distance(transform.position, playerTransform.position) < playerMovementScript.distToPickUpGun  Input.GetButtonDown("Use Key")  playerMovementScript.waitFrameForSwitchGuns <= 0)
	{
		playerMovementScript.currentGun.GetComponent(GunScript).beingHeld = false;
		playerMovementScript.currentGun.GetComponent(GunScript).countToThrow = 2;
		playerMovementScript.currentGun = gameObject;
		beingHeld = true;
		targetYRotation = cameraObject.GetComponent(MouseLookScript).yRotation - 180;
		playerMovementScript.waitFrameForSwitchGuns = 2;
	}
}
}

PlayerMovementScript.js

var currentGun : GameObject;
var distToPickUpGun : float = 6;
var throwGunUpForce : float = 100;
var throwGunForwardForce : float = 300;
var waitFrameForSwitchGuns : int = -1;

var walkAcceleration : float = 5;
var walkAccelAirRacio : float = 0.1;
var walkDeacceleration : float = 5;
@HideInInspector
var walkDeaccelerationVolx : float;
@HideInInspector
var walkDeaccelerationVolz : float;

var cameraObject : GameObject;
var maxWalkSpeed : float = 20;
@HideInInspector
var horizontalMovement : Vector2;

var jumpVelocity : float = 20;
@HideInInspector
var grounded : boolean = false;
var maxSlope : float = 60;

var crouchRacio : float = 0.3;
var transitionToCrouchSec : float = 0.2;
var crouchingVelocity : float;
var currentCrouchRacio : float = 1;
var originalLocalScaleY : float;
var crouchLocalScaleY : float;
var collisionDetectionSphere : GameObject;

function Awake ()
{
	currentCrouchRacio = 1;
	originalLocalScaleY = transform.localScale.y;
	crouchLocalScaleY = transform.localScale.y * crouchRacio;
}

function LateUpdate () 
{
	waitFrameForSwitchGuns -= 1;

	transform.localScale.y = Mathf.Lerp(crouchLocalScaleY, originalLocalScaleY, currentCrouchRacio);
	if (Input.GetButton("Crouch"))
		currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 0, crouchingVelocity, transitionToCrouchSec);
	if (Input.GetButton("Crouch") == false  collisionDetectionSphere.GetComponent(CollsionDetectionSphereScript).collisionDetected == false)
		currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 1, crouchingVelocity, transitionToCrouchSec);
	
	horizontalMovement = Vector2(rigidbody.velocity.x, rigidbody.velocity.z);
	if (horizontalMovement.magnitude > maxWalkSpeed)
	{
		horizontalMovement = horizontalMovement.normalized;
		horizontalMovement *= maxWalkSpeed;		
	}
	rigidbody.velocity.x = horizontalMovement.x;
	rigidbody.velocity.z = horizontalMovement.y;
	
	if (grounded){
		rigidbody.velocity.x = Mathf.SmoothDamp(rigidbody.velocity.x, 0, walkDeaccelerationVolx, walkDeacceleration);
		rigidbody.velocity.z = Mathf.SmoothDamp(rigidbody.velocity.z, 0, walkDeaccelerationVolz, walkDeacceleration);}
	
	transform.rotation = Quaternion.Euler(0, cameraObject.GetComponent(MouseLookScript).currentYRotation, 0);
	
	if (grounded)
		rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * Time.deltaTime, 0, Input.GetAxis("Vertical") * walkAcceleration * Time.deltaTime);
	else
		rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * walkAccelAirRacio * Time.deltaTime, 0, Input.GetAxis("Vertical") * walkAcceleration * walkAccelAirRacio * Time.deltaTime);
			
	if (Input.GetButtonDown("Jump")  grounded)
		rigidbody.AddForce(0,jumpVelocity,0);
}

function OnCollisionStay (collision : Collision)
{
	for (var contact : ContactPoint in collision.contacts)
	{
		if (Vector3.Angle(contact.normal, Vector3.up) < maxSlope)
			grounded = true;
	}
}

function OnCollisionExit ()
{
	grounded = false;
}

CollisionDetectionSphereScript.js

var floatAbove : float = 0.1;
var playerCapsuleTransform : Transform;
@HideInInspector
var collisionDetected : boolean = false;

function Update () 
{
	transform.position.x = playerCapsuleTransform.position.x;
	transform.position.z = playerCapsuleTransform.position.z;
	transform.position.y = playerCapsuleTransform.position.y + ((playerCapsuleTransform.GetComponent(Collider).height * playerCapsuleTransform.localScale.y) / 2) + (transform.localScale.y / 2) + floatAbove;
}

function OnCollisionStay (collision : Collision)
{
	if (collision.transform.tag == "Level Parts")
		collisionDetected = true;
}

function OnCollisionExit ()
{
	collisionDetected = false;
}

DestroyAfterTimeScript.js

var destroyAfterTime : float = 30;
var destroyAfterTimeRandomization : float = 0;
@HideInInspector
var countToTime : float;

function Awake ()
{
	destroyAfterTime += Random.value * destroyAfterTimeRandomization;
}

function Update () 
{
	countToTime += Time.deltaTime;
	if (countToTime >= destroyAfterTime)
		Destroy(gameObject);
}

MouseLookScript.js

var defaultCameraAngle : float = 60;
@HideInInspector
var currentTargetCameraAngle : float = 60;
@HideInInspector
var racioZoom : float = 1;
@HideInInspector
var racioZoomV : float;

var racioZoomSpeed : float = 0.2;

var lookSensitivity : float = 5;
@HideInInspector
var yRotation : float;
@HideInInspector
var xRotation : float;
@HideInInspector
var currentYRotation : float;
@HideInInspector
var currentXRotation : float;
@HideInInspector
var yRotationV : float;
@HideInInspector
var xRotationV : float;
var lookSmoothDamp : float = 0.1;
@HideInInspector
var currentAimRacio : float = 1;

var headbobSpeed : float = 1;
@HideInInspector
var headbobStepCounter : float;
var headbobAmountX : float = 1;
var headbobAmountY : float = 1;
@HideInInspector
var parentLastPos : Vector3;
var eyeHeightRacio : float = 0.9;

function Awake ()
{
	parentLastPos = transform.parent.position;
}

function Update () 
{
	if (transform.parent.GetComponent(PlayerMovementScript).grounded)
		headbobStepCounter += Vector3.Distance(parentLastPos, transform.parent.position) * headbobSpeed;
	transform.localPosition.x = Mathf.Sin(headbobStepCounter) * headbobAmountX * currentAimRacio;
	transform.localPosition.y = (Mathf.Cos(headbobStepCounter * 2) * headbobAmountY * currentAimRacio) + (transform.parent.localScale.y * eyeHeightRacio) - (transform.parent.localScale.y / 2);
	
	parentLastPos = transform.parent.position;

	if (currentAimRacio == 1)
		racioZoom = Mathf.SmoothDamp(racioZoom, 1, racioZoomV, racioZoomSpeed);
	else
		racioZoom = Mathf.SmoothDamp(racioZoom, 0, racioZoomV, racioZoomSpeed);
		
	camera.fieldOfView = Mathf.Lerp(currentTargetCameraAngle, defaultCameraAngle, racioZoom);

	yRotation += Input.GetAxis("Mouse X") * lookSensitivity * currentAimRacio;
	xRotation -= Input.GetAxis("Mouse Y") * lookSensitivity * currentAimRacio;
	
	xRotation = Mathf.Clamp(xRotation, -90, 90);
	
	currentXRotation = Mathf.SmoothDamp(currentXRotation, xRotation, xRotationV, lookSmoothDamp);
	currentYRotation = Mathf.SmoothDamp(currentYRotation, yRotation, yRotationV, lookSmoothDamp);
	
	transform.rotation = Quaternion.Euler(currentXRotation, currentYRotation, 0);
}

Download the zip file of FPS1.23 (Same file you see me using in the tutorials):
817321–30259–$FPS1.23.zip (3.73 MB)

wow

speeding programming Nice Man

very good work you developer games

Thanks omarzonex :slight_smile:

You really deserve a medal, thanks for all those tutorials out there you help people a lot and you made me understand those weapon bob movements with mathf, thanks :).

thanks man. I really enjoy making these videos and I love that people are finding them so helpful. I’m glad I could help :slight_smile:

Hi!

I think that these tutorials are epic! So thanks alot for making them.

But I have a problem when importing a model to replace the gun. Everything goes fine, until I start the game and start looking around.

The gun follows the rotation of the camera, so that when I look down, the model stays at it’s same origin, and just rotates down.
So what I see from the FPS camera, is the handle and the underside of the gun… It makes it hard to aim, and it looks not right.

When I make a gun from boxes in unity, like you do in the tutorials, everything works fine.
Do you have any idea what causes this?

hmm. did you make the gun model a child of an empty game object? that’s an easy way to change the gun’s origin point.

Hello! I’m getting quite the interesting error, along with my ‘physical’ collision-sphere not moving from its spot over my head.

NullReferenceException: Object reference not set to an instance of an object
Boo.Lang.Runtime.RuntimeServices.InvokeBinaryOperator (System.String operatorName, System.Object lhs, System.Object rhs)
CollisionDetectionSphereScript.Update () (at Assets/Scripts/CollisionDetectionSphereScript.js:10)

I’ve gone over your video several times ensuring that everything is spell correctly and that I didn’t leave out any parentheses, and I haven’t been able to find anything.

CollisionDetectionSphereScript.js

    var floatAbove : float = 0.1;
    var playerCapsuleTransform : Transform;
    @HideInInspector
    var collisionDetected : boolean = false;
     
    function Update ()
    {
        transform.position.x = playerCapsuleTransform.position.x;
        transform.position.z = playerCapsuleTransform.position.z;
        transform.position.y = playerCapsuleTransform.position.y + ((playerCapsuleTransform.GetComponent(Collider).height * playerCapsuleTransform.localScale.y) / 2) + (transform.localScale.y / 2) + floatAbove;
    }
     
    function OnCollisionStay (collision : Collision)
    {
        if (collision.transform.tag == "Level Parts")
            collisionDetected = true;
    }
     
    function OnCollisionExit ()
    {
        collisionDetected = false;
    }

PlayerMovement.js

var walkAcceleration : float = 5;
var walkAccelAirRacio : float = 0.1;
var walkDeacceleration : float = 5;
@HideInInspector
var walkDeaccelerationVolx : float;
@HideInInspector
var walkDeaccelerationVolz : float;


var cameraObject : GameObject;
var maxWalkSpeed : float = 20;
@HideInInspector
var horizontalMovement : Vector2;
var jumpVelocity : float = 20;
@HideInInspector
var grounded : boolean = false;
var maxSlope : float = 60;

//crouching
var crouchRacio : float = 0.3;
var transitionToCrouchSec : float = 0.2;
@HideInInspector
var crouchVelocity : float;
var currentCrouchRacio : float = 1;
@HideInInspector
var originalLocalScaleY : float;
@HideInInspector
var crouchLocalScaleY : float;
//end crouching and collision detection
var collisionDetectionSphere : GameObject;

function Awake ()
{
	currentCrouchRacio = 1;
	originalLocalScaleY = transform.localScale.y;
	crouchLocalScaleY = transform.localScale.y * crouchRacio;
}

function Update () 
{
	transform.localScale.y = Mathf.Lerp(crouchLocalScaleY, originalLocalScaleY, currentCrouchRacio);
	if(Input.GetButton("Crouch"))
		currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 0, crouchVelocity, transitionToCrouchSec);
	if(Input.GetButton("Crouch") == false  collisionDetectionSphere.GetComponent(CollisionDetectionSphereScript).collisionDetected == false)
		currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 1, crouchVelocity, transitionToCrouchSec);

	horizontalMovement = Vector2(rigidbody.velocity.x, rigidbody.velocity.z);
	if (horizontalMovement.magnitude > maxWalkSpeed)
	{
		horizontalMovement = horizontalMovement.normalized;
		horizontalMovement *= maxWalkSpeed;
	}
	rigidbody.velocity.x = horizontalMovement.x;
	rigidbody.velocity.z = horizontalMovement.y;
	
	if (grounded){
		rigidbody.velocity.x = Mathf.SmoothDamp(rigidbody.velocity.x, 0, walkDeaccelerationVolx, walkDeacceleration);
		rigidbody.velocity.z = Mathf.SmoothDamp(rigidbody.velocity.z, 0, walkDeaccelerationVolz, walkDeacceleration);
	}
	
	
	transform.rotation = Quaternion.Euler(0, cameraObject.GetComponent(MouseLookScript).currentYRotation, 0);
//Moves player based on WASD input
	if(grounded)	
		rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * Time.deltaTime, 0, Input.GetAxis("Vertical") * walkAcceleration * Time.deltaTime);
	else
		rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * walkAccelAirRacio * Time.deltaTime, 0, Input.GetAxis("Vertical") * walkAcceleration * walkAccelAirRacio * Time.deltaTime);
	
	
	if(Input.GetButtonDown("Jump")  grounded)
		rigidbody.AddForce(0, jumpVelocity,0);
}


function OnCollisionStay (collision: Collision)
{
	for (var contact : ContactPoint in collision.contacts)
	{
		if (Vector3.Angle(contact.normal, Vector3.up) < maxSlope)
			grounded = true;
	}
}

function OnCollisionExit ()
{
 grounded = false;
}

hey im having errors such as the variable of gunscript outsidebox is not assiagned and other things with the playermovement script are not assiagned an im really confused about wat i shud assiagn to them please help me quick :confused:

Hey! i love your tutorials, and I am happily enjoying them, but I am getting a really annoying error. I keep getting spammed in the console "NullReferenceException: Object reference not set to an instance of an object
GunScript.LateUpdate () (at Assets/GunScript.js:70) "
And I get what ETeeski gets at 51:39 in tutorial 1.23, and I cant fix it, any help?

GunScript:
var beingHeld : boolean = false;
var outsideBox : GameObject;
@HideInInspector
var countToThrow : int = -1;
@HideInInspector
var playerTransform : Transform;
@HideInInspector
var playerMovementScript : PlayerMovementScript;

var cameraObject : GameObject;
@HideInInspector
var targetXRotation : float;
@HideInInspector
var targetYRotation : float;
@HideInInspector
var targetXRotationV : float;
@HideInInspector
var targetYRotationV : float;

var rotateSpeed : float = 0.3;

var holdHeight : float = -0.5;
var holdSide : float = 0.5;
var racioHipHold : float = 1;
var hipToAimSpeed : float = 0.1;
@HideInInspector
var racioHipHoldV : float;

var aimRacio : float = 0.4;

var zoomAngle : float = 30;

var fireSpeed : float = 15;
@HideInInspector
var waitTillNextFire : float = 0;
var bullet : GameObject;
var bulletSpawn : GameObject;

var shootAngleRandomizationAiming : float = 2;
var shootAngleRandomizationNotAiming : float = 5;

var recoilAmount : float = 0.5;
var recoilRecoverTime : float = 0.2;
@HideInInspector
var currentRecoilZPos : float;
@HideInInspector
var currentRecoilZPosV : float;

var bulletSound : GameObject;
var muzzleFlash : GameObject;

var gunbobAmountX : float = 0.5;
var gunbobAmountY : float = 0.5;
var currentGunBobX : float;
var currentGunBobY : float;

function Awake ()
{
countToThrow = -1;
playerTransform = GameObject.FindWithTag(“Player”).transform;
playerMovementScript = GameObject.FindWithTag(“Player”).GetComponent(PlayerMovementScript);
cameraObject = GameObject.FindWithTag(“MainCamera”);
}

function LateUpdate ()
{
if(beingHeld)
{
rigidbody.useGravity = false;
outsideBox.GetComponent(Collider).enabled = false;

currentGunBobX = Mathf.Sin(cameraObject.GetComponent(MouseLookScript).headbobStepCounter) * gunbobAmountX * racioHipHold;
currentGunBobY = Mathf.Cos(cameraObject.GetComponent(MouseLookScript).headbobStepCounter * 2) * gunbobAmountY * -1 * racioHipHold;

var holdMuzzleFlash : GameObject;
var holdSound : GameObject;
if(Input.GetButton(“Fire1”))
{
if(waitTillNextFire <= 0)
{
if(bullet)
Instantiate(bullet,bulletSpawn.transform.position, bulletSpawn.transform.rotation);
if(bulletSound)
holdSound = Instantiate(bulletSound,bulletSpawn.transform.position, bulletSpawn.transform.rotation);
if(muzzleFlash)
holdmuzzleFlash = Instantiate(muzzleFlash,bulletSpawn.transform.position, bulletSpawn.transform.rotation);
targetXRotation += (Random.value - 0.5) * Mathf.Lerp(shootAngleRandomizationAiming, shootAngleRandomizationNotAiming, racioHipHold);
targetYRotation += (Random.value - 0.5) * Mathf.Lerp(shootAngleRandomizationAiming, shootAngleRandomizationNotAiming, racioHipHold);
currentRecoilZPos -= recoilAmount;
waitTillNextFire = 1;
}
}
waitTillNextFire -= Time.deltaTime * fireSpeed;

if(holdSound)
holdSound.transform.parent = transform;
if(holdmuzzleFlash)
holdmuzzleFlash.transform.parent = transform;

currentRecoilZPos = Mathf.SmoothDamp( currentRecoilZPos, 0, currentRecoilZPosV, recoilRecoverTime);

cameraObject.GetComponent(MouseLookScript).currentTargetCameraAngle = zoomAngle;

if(Input.GetButton(“Fire2”)){
cameraObject.GetComponent(MouseLookScript).currentAimRacio = aimRacio;
racioHipHold = Mathf.SmoothDamp(racioHipHold, 0, racioHipHoldV, hipToAimSpeed);}
if(Input.GetButton(“Fire2”) == false){
cameraObject.GetComponent(MouseLookScript).currentAimRacio = 1;
racioHipHold = Mathf.SmoothDamp(racioHipHold, 1, racioHipHoldV, hipToAimSpeed);}

transform.position = cameraObject.transform.position + (Quaternion.Euler(0,targetYRotation,0) * Vector3(holdSide * racioHipHold + currentGunBobX, holdHeight + currentGunBobY * racioHipHold, 0) + Quaternion.Euler(targetXRotation, targetYRotation, 0) * Vector3(0,0, currentRecoilZPos));

targetXRotation = Mathf.SmoothDamp( targetXRotation, cameraObject.GetComponent(MouseLookScript).xRotation, targetXRotationV, rotateSpeed);
targetYRotation = Mathf.SmoothDamp( targetYRotation, cameraObject.GetComponent(MouseLookScript).yRotation, targetYRotationV, rotateSpeed);

transform.rotation = Quaternion.Euler(targetXRotation, targetYRotation, 0);
}
if(!beingHeld)
{
rigidbody.useGravity = true;
outsideBox.GetComponent(Collider).enabled = true;

countToThrow -= 1;
if (countToThrow == 0)
rigidbody.AddRelativeForce(0, playerMovementScript.throwGunUpForce, playerMovementScript.throwGunForwardForce);

if(Vector3.Distance(transform.position, playerTransform.position) < playerMovementScript.distToPickUpGun Input.GetButtonDown(“Use Key”) playerMovementScript.waitFrameForSwitchGuns <= 0)
{
playerMovementScript.currentGun.GetComponent(GunScript).beingHeld = false;
playerMovementScript.currentGun.GetComponent(GunScript).countToThrow = 2;
playerMovementScript.currentGun = gameObject;
beingHeld = true;
targetYRotation = cameraObject.GetComponent(MouseLookScript).yRotation - 180;
playerMovementScript.waitFrameForSwitchGuns = 2;
}
}
}

Player Movement Script:
var currentGun : GameObject;
var distToPickUpGun : float = 6;
var throwGunUpForce : float = 100;
var throwGunForwardForce : float = 300;
var waitFrameForSwitchGuns : int = -1;

var walkAcceleration : float = 5;
var walkAccelAirRacio : float = 0.1;
var walkDeacceleration : float = 5;
@HideInInspector
var walkDeaccelerationVolx : float;
@HideInInspector
var walkDeaccelerationVolz : float;

var cameraObject : GameObject;
var maxWalkSpeed : float = 20;
@HideInInspector
var horizontalMovement : Vector2;

var jumpVelocity : float = 20;
@HideInInspector
var grounded : boolean = false;
var maxSlope : float = 60;

var crouchRacio : float = 0.3;
var transitionToCrouchSec : float = 0.2;
var crouchingVelcoity : float;
var currentCrouchRacio : float = 1;
var originalLocalScaleY : float;
var crouchLocalScaleY : float;
var collisionDetectionSphere : GameObject;

function Awake ()
{
currentCrouchRacio = 1;
originalLocalScaleY = transform.localScale.y;
crouchLocalScaleY = transform.localScale.y * crouchRacio;
}

function LateUpdate ()
{
waitFrameForSwitchGuns -= 1;

transform.localScale.y = Mathf.Lerp(crouchLocalScaleY, originalLocalScaleY, currentCrouchRacio);
if (Input.GetButton(“Crouch”))
currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 0, crouchingVelcoity, transitionToCrouchSec);
if(Input.GetButton(“Crouch”) == false collisionDetectionSphere.GetComponent(CollisionDecectionSphereScript).collisionDetected == false)
currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 1, crouchingVelcoity, transitionToCrouchSec);

horizontalMovement = Vector2(rigidbody.velocity.x, rigidbody.velocity.z);
if(horizontalMovement.magnitude > maxWalkSpeed)
{
horizontalMovement = horizontalMovement.normalized;
horizontalMovement *= maxWalkSpeed;
}
rigidbody.velocity.x = horizontalMovement.x;
rigidbody.velocity.z = horizontalMovement.y;

if(grounded){
rigidbody.velocity.x = Mathf.SmoothDamp(rigidbody.velocity.x, 0, walkDeaccelerationVolx, walkDeacceleration);
rigidbody.velocity.z = Mathf.SmoothDamp(rigidbody.velocity.z, 0, walkDeaccelerationVolz, walkDeacceleration);}

transform.rotation = Quaternion.Euler(0, cameraObject.GetComponent(MouseLookScript).currentYRotation, 0);

if(grounded)
rigidbody.AddRelativeForce(Input.GetAxis(“Horizontal”) * walkAcceleration * Time.deltaTime, 0, Input.GetAxis(“Vertical”) * walkAcceleration * Time.deltaTime);
else
rigidbody.AddRelativeForce(Input.GetAxis(“Horizontal”) * walkAcceleration * walkAccelAirRacio * Time.deltaTime, 0, Input.GetAxis(“Vertical”) * walkAcceleration * walkAccelAirRacio * Time.deltaTime);

if(Input.GetButtonDown(“Jump”) grounded)
rigidbody.AddForce(0,jumpVelocity,0);
}

function OnCollisionStay (collision : Collision)
{
for(var contact : ContactPoint in collision.contacts)
{
if(Vector3.Angle(contact.normal, Vector3.up) < maxSlope)
grounded = true;
}
}

function OnCollisionExit ()
{
grounded = false;
}

Hi SIR ( EteeskiTutorials ) ,. First of all i want to tell you that your tutorials are super epic they helped me a lot ,… And thanks for the script Too,…and i have got a request for you that can you please update the Download which is the zip file (FPS1.23) ,. because i actually don’t use the threads to get the script i use the one which is in the project ( FPS1.23 ) and now when i see your tutorial i found that the script was not complete as seen on the tutorials SO CAN YOU PLEASE UPDATE THEM , If you cannot or if you don’t have time then also there is no problem ,… AND YOU HAVE GIVEN THIS MUCH TUTORIALS FOR THE BEGINNERS THAT IS ALSO MUCH I REALLY APRECIATE THAT ,… OK THANKS AND HOPE YOU REPLY AND UPDATE THE PROJECT :wink:

Hey I was having trouble with the collision detection sphere script. I am getting an error that says height is not a member of unityengine.collider. Any suggestions?

Sooo Im getting the null reference exception error and I know that means there’s just a stupid mistake somewhere. I really hope that’s not it because I’ve been searching forever for it! I really don’t want to be another dumb person who spams you with silly errors, but your are my last hope. YOU ARE MY SAVIOR! My code is below:—I’ve added a bunch of comments to help me understand stuff, so don’t mind them :slight_smile: Also I took out all the crouch stuff. That should’t effect it though.

Player Inpspector Values---------------------------------------------------------------------------------------------------------------------
Walk Acceleration - 2000
Walk Deacceleration - 0.15
Walk Accel Air Raci0.1o -
Max Walk Speed10 -
Jump Velocity -3
Max Slope - 60
Camera Object - Main Camera
Current Gun - UMP-45
Dist To Pick Up Gun - 10
Throw Gun Up Force - 100
Throw Gun Forward Force - 300
Wait Frame For Switch Guns - -1

I have two different weapons: A ump45 and an m4a1. The ump45 is the default gun

ump45 Inpspector Values---------------------------------------------------------------------------------------------------------------------
RotateSpeed - 0.15
Hold Height - 0.2
Hold Side - 0.38
Racio Hip Hold - 1
Hip To Aim Speed - 0.1
Hold Distance - 0
Zoom Angle - 40
Aiming Mouse Sensitivity - 0.4
Fire Speed - 15
Bullet - bullet
Bullet Spawn - BulletSpawn
Shoot Angle Randomization Aim - 3
Shoot Angle Randomization Not Aiming - 10
Recoil Amount - 0.1
Recoil Recover Time - 0.15
Bullet Sound - umpGunSound
Muzzle Flash - muzzleFlash
Muzzle Smoke - muzzleSmoke
Gunbob Amount X - 0.07
Gunbob Amount Y - 0.04
Being Held - yes
Outside Box - umpCollider

m4a1Inpspector Values-----------------------------------------------------------------------------------------------------------------------
RotateSpeed - 0.15
Hold Height - 0
Hold Side - 0
Racio Hip Hold -1
Hip To Aim Speed - 0.1
Hold Distance - 0.18
Zoom Angle - 30
Aiming Mouse Sensitivity - 0.4
Fire Speed - 10
Bullet - bullet
Bullet Spawn - BulletSpawn
Shoot Angle Randomization Aim - 3
Shoot Angle Randomization Not Aiming - 10
Recoil Amount - 0.1
Recoil Recover Time - 0.15
Bullet Sound - m4a1GunSound
Muzzle Flash - muzzleFlash
Muzzle Smoke - muzzleSmoke
Gunbob Amount X - 0.01
Gunbob Amount Y - 0.02
Being Held - no
Outside Box - umpCollider

var walkAcceleration : float = 5.0;//How quickly the player's speed increases
var walkDeacceleration : float = 5.0;
var walkAccelAirRacio : float = 0.1;
var maxWalkSpeed : float = 15;//The maximum speed the player can walk
var jumpVelocity : float = 3;//This basically how much velocity force will be applied when jumping
var maxSlope : float = 60;//This is the max angle of an object at wich the player can be standing on and be able to jump.
var cameraObject : GameObject;//Accessses the player's camera
var currentGun : GameObject;
var distToPickUpGun : float = 10;
var throwGunUpForce : float = 100;
var throwGunForwardForce : float = 300;
var waitFrameForSwitchGuns : int = -1;

@HideInInspector
var walkDeaccelerationVelX : float;
@HideInInspector
var walkDeaccelerationVelZ : float;
@HideInInspector//Hides the variable from the inspector without making it private
var xzMovement : Vector2;//Shows us the speed in each individual direction on an XZ plane ie: flat, ground.
@HideInInspector
var grounded : boolean = false;

function Awake ()
{

}

function Update ()
{
    waitFrameForSwitchGuns -= 1;

    xzMovement = Vector2(rigidbody.velocity.x,rigidbody.velocity.z);//Left and right direction in xzMovement is equal to our velocity on the x axis(-x,x).
                                                                   //This applies similarly to the forward and backward floats on the z axis (-z,z).
    if(xzMovement.magnitude > maxWalkSpeed)//Magnitude is the square root of the total of each vector value * 2. Example (square root of (x+x,y+y))
                                          //If out magnitude is higher than our max magnitude, we stop the acceleration.
    {
        xzMovement = xzMovement.normalized;//Normalizing a Vector takes all the values and limits their magnitude to one, but still keeps the vectors direction.
        xzMovement *= maxWalkSpeed;//Multiplying the Vector2, xzMovement, by maxWalkSpeed multiplies each individual value in the vector by maxWalkSpeed.
                                  //In the previous line of code, normalizing the vector sets each value inside it to 1. Multiplying 1 * maxWalkSpeed will set it equal to maxWalkSpeed.
                                  //That successfully caps the players magnitude (speed).
    }
    rigidbody.velocity.x = xzMovement.x;//This restricts the left an right speed to our "x"zMovement vector. That vector cuts of at a certain magnitude, limiting our speed.
    rigidbody.velocity.z = xzMovement.y;//This restricts the forward an backward speed to our x"z"Movement vector. That vector cuts of at a certain magnitude, limiting our speed.

    transform.rotation = Quaternion.Euler(0,cameraObject.GetComponent(MouseLookScript).currentYRotation,0);//Using the Euler is easier than using Quaternion by itself, just go with it.
                                                                                                          //The line above is setting the capsules y rotation to the cameras y rotation.
    if (grounded)//Inside this if statement is the code that gives our player full movement control. To have full control you have to be grounded, otherwise your movement is limited (while falling or jumping).
    {
        rigidbody.AddRelativeForce(Input.GetAxis("Horizontal")*walkAcceleration*Time.deltaTime,0,Input.GetAxis("Vertical")*walkAcceleration*Time.deltaTime);//This puts everything we've done above into action.
        rigidbody.velocity.x = Mathf.SmoothDamp(rigidbody.velocity.x,0,walkDeaccelerationVelX, walkDeacceleration);//Mathf.SmoothDamp->(current value, goal value, velocity, max time to reach goal value)
        rigidbody.velocity.z = Mathf.SmoothDamp(rigidbody.velocity.z,0,walkDeaccelerationVelZ, walkDeacceleration);//Mathf.SmoothDamp->(current value, goal value, velocity, max time to reach goal value)
    //^Adds force on local coordinates. It requires a Vector3 to know in what direction to apply force. EX. If you press left, that returns -1 on the horizontal axis. As long as you have it
    //held down -1 will be multiplied by 5 (walkAcceleration) every frame----> frame1 = 5, frame2 = 25, frame3 = 125..and so on;
    }
    else//If your not grounded, the below text will run.
    {
        rigidbody.AddRelativeForce(Input.GetAxis("Horizontal")*walkAcceleration*walkAccelAirRacio*Time.deltaTime,0,Input.GetAxis("Vertical")*walkAcceleration*walkAccelAirRacio*Time.deltaTime);//The floats that are-
        //being fed in to represent the amount of velocity to apply are being multiplied by 0.1 which makes the number smaller. This lowers the amount of velocity able to be applied, therefore you have less control.
    }
    if (Input.GetKeyDown(KeyCode.Space) && grounded)//When the player has pressed space and the player is grounded(on the ground), the code within the brackets below will be run.
    {
        rigidbody.AddForce(0,jumpVelocity*100,0);//Adds upwards velocity to create a jump. The variable jumpVelocity determines how much force is applies in the y value of the vector.
    }
}
function OnCollisionStay (collision : Collision)//While the players collider is touching another collider, the lines inside the function will be called.
{
    for (var contact : ContactPoint in collision.contacts)//We made a variable called contact. It's type is ContactPoint, which returns an array with the points at which our collider touches other colliders.
    {                                                     //For every contact point in the array, the following lines will be run.
        if (Vector3.Angle(contact.normal,Vector3.up)<maxSlope)//Vector3.Angle returns the angle measure between an up vector(vertical line or (0,1,0)) and a vector thats perpendicular to the collider we collided with.
        {
            grounded = true;//If the above statement is true, our grounded boolean is true. If our grounded boolean is true, we are touching a collider that isn't too steep. In the function Update, if we are grounded,
                            //we can jump. Now we can jump the right way ie No double jumps of jumping off walls.
        }
    }
}
function OnCollisionExit ()//When we aren't touching anything, the line below is run.
{
    grounded = false;//If grounded is equal ro false, we can't jump. It doesn't matter if we press space.
}
[CODE]

[CODE]
@HideInInspector
var cameraObject : GameObject;//This holds the player's cameras info.
var rotateSpeed : float = 0.3;//This is the maximum time it can take for the gun to catch up to the camera's rotation.
var holdHeight : float =-0.5;//The amount added or subtracted from the ameras position in which the gun will be located in the y-axis.
var holdSide : float =0.5;//The amount added or subtracted from the ameras position in which the gun will be located in the x-axis.
var racioHipHold : float = 1;
@HideInInspector
var targetXRotation : float;//The rotation that the gun tries to reach on the x-axis.
@HideInInspector
var targetYRotation : float;//The rotation that the gun tries to reach on the y-axis.
@HideInInspector
var targetXRotationV : float;//The guns rotation velocity on the x-axis.
@HideInInspector
var targetYRotationV : float;//The guns rotation velocity on the y-axis.
@HideInInspector

var racioHipHoldV : float;
var hipToAimSpeed : float = 0.1;
var holdDistance : float = 0.1;//The amount added or subtracted from the ameras position in which the gun will be located in the z-axis.
var zoomAngle : float = 30;
var aimingMouseSensitivity : float = 0.4;

var fireSpeed : float = 15;
var bullet : GameObject;
var bulletSpawn : GameObject;
@HideInInspector
var waitTilNextFire : float = 0;

var shootAngleRandomizationAiming : float = 5;
var shootAngleRandomizationNotAiming : float = 15;

var recoilAmount : float = 0.5;
var recoilRecoverTime : float = 0.2;
@HideInInspector
var currentRecoilZPos : float;
@HideInInspector
var currentRecoilZPosV : float;

var bulletSound : GameObject;
var muzzleFlash : GameObject;
var muzzleSmoke : GameObject;

var gunbobAmountX : float = 0.5;
var gunbobAmountY : float = 0.5;
@HideInInspector
var currentGunbobX : float;
@HideInInspector
var currentGunbobY : float;

var beingHeld : boolean = false;
var outsideBox : GameObject;
@HideInInspector
var countToThrow : int = -1;
@HideInInspector
var playerTransform : Transform;
@HideInInspector
var playerMovementScript : PlayerMovementScript;

function Awake ()
{
    countToThrow = -1;
    playerTransform = GameObject.FindWithTag("Player").transform;
    playerMovementScript = GameObject.FindWithTag("Player").GetComponent(PlayerMovementScript);
    cameraObject = GameObject.FindWithTag ("MainCamera");
}
function LateUpdate ()
{
    if (beingHeld == true)
    {
        rigidbody.useGravity = false;
        outsideBox.GetComponent(Collider).enabled = false;
    
        currentGunbobX = Mathf.Sin(cameraObject.GetComponent(MouseLookScript).headbobStepCounter)*gunbobAmountX * racioHipHold;
        currentGunbobY = Mathf.Cos(cameraObject.GetComponent(MouseLookScript).headbobStepCounter*2)*gunbobAmountY*-1 * racioHipHold;
    
        var holdMuzzleFlash : GameObject;
        var holdSound : GameObject;
        var holdMuzzleSmoke : GameObject;
        if (Input.GetMouseButton(0))
        {
            if (waitTilNextFire <= 0)
            {
                if (bullet)
                {
                    Instantiate(bullet,bulletSpawn.transform.position,bulletSpawn.transform.rotation);
                }
                if (bulletSound)
                {
                    holdSound = Instantiate(bulletSound,bulletSpawn.transform.position,bulletSpawn.transform.rotation);
                }
                if (muzzleFlash)
                {
                    holdMuzzleFlash = Instantiate(muzzleFlash,bulletSpawn.transform.position,bulletSpawn.transform.rotation);
                }
                if (muzzleSmoke)
                {
                    holdMuzzleSmoke = Instantiate(muzzleSmoke,bulletSpawn.transform.position,bulletSpawn.transform.rotation);
                }
                targetXRotation += (Random.value-1) * Mathf.Lerp(shootAngleRandomizationAiming,shootAngleRandomizationNotAiming,racioHipHold);
                targetYRotation += (Random.value-0.5) * Mathf.Lerp(shootAngleRandomizationAiming,shootAngleRandomizationNotAiming,racioHipHold);
                currentRecoilZPos -= recoilAmount;
                waitTilNextFire = 1;
            }
        }
        waitTilNextFire -= Time.deltaTime * fireSpeed;
        if (holdSound)
        {
            holdSound.transform.parent = transform;
        }
        if (holdMuzzleFlash)
        {
            holdMuzzleFlash.transform.parent = transform;
        }
        currentRecoilZPos = Mathf.SmoothDamp(currentRecoilZPos,0,currentRecoilZPosV,recoilRecoverTime);
        cameraObject.GetComponent(MouseLookScript).currentTargetCameraAngle = zoomAngle;
        if (Input.GetMouseButton(1))
        {
            cameraObject.GetComponent(MouseLookScript).currentAimRacio = aimingMouseSensitivity;//The camera's look sensitivity is multiplied by aimingMouseSensitivity, which defaults to 1.
            //If it is smaller than one, the aim sensitivity lessens.
            racioHipHold = Mathf.SmoothDamp(racioHipHold,0,racioHipHoldV,hipToAimSpeed);//The ratioHipHold will decrease from a default of 1 to 0.
        }
        if (!Input.GetMouseButton(1))
        {
            cameraObject.GetComponent(MouseLookScript).currentAimRacio = 1;//The camera's look sensitivity is multiplied by currentAimRatio, which defaults to 1. Now that we aren't zooming, the ratio returns to 1.
            racioHipHold = Mathf.SmoothDamp(racioHipHold,1,racioHipHoldV,hipToAimSpeed);//The ratioHipHold will increase from of 0 to the default 1.
        }
    
        transform.position = cameraObject.transform.position + (Quaternion.Euler(0,targetYRotation,0)*Vector3(holdSide*racioHipHold+currentGunbobX,holdHeight*racioHipHold+currentGunbobY,holdDistance)+Quaternion.Euler(targetXRotation,targetYRotation,0)*Vector3(0,0,currentRecoilZPos));
        //The gun's position is equal tothe camera's position.
        //Then we multiply the quaternion by our Vector3. Multiplying a Quaternion by a Vector3 rotates the Vector3 to the direction of the Quaternion. Our targetRotation is smotthy rotated to face our camera's rotation.
        //Now our gun is smoothly rotating to follow the camera's rotation! Remember, everything inside of the parenthesis ends up returning one Vector3 for the position to be equal to. The quaternion could be multiplied
        //after the Vector3. The Vector3 holds the values for the offset on each axis for our gun. that way the gun isn't right on top of the camera. Those values are multiplied by our racioHipHold which is either 0 or 1.
        //If its zero, the offsets are now zero because any number multiplied by a zero is zero. Now that the guns position is zeroed out, it's right on the camera, which is where it should be if you're looking down a sight
    
        targetXRotation = Mathf.SmoothDamp(targetXRotation,cameraObject.GetComponent(MouseLookScript).xRotation,targetXRotationV,rotateSpeed);//This is making our rotation smoothly follow the cameras rotation.
        targetYRotation = Mathf.SmoothDamp(targetYRotation,cameraObject.GetComponent(MouseLookScript).yRotation,targetYRotationV,rotateSpeed);//^^This simulate sweapon sway!
    
        transform.rotation = Quaternion.Euler(targetXRotation,targetYRotation,0);//The huge comment section above is covering the guns position, this line right here sets our gun's rotation to be equal to the variables that
        //contain the values to simulate a delayed follow or weapon sway.
    }
    if (!beingHeld)
    {
        rigidbody.useGravity = true;
        outsideBox.GetComponent(Collider).enabled = true;
        countToThrow -= 1;
        if (countToThrow == 0)
        {
            rigidbody.AddRelativeForce (0,playerMovementScript.throwGunUpForce,playerMovementScript.throwGunForwardForce);
        }
        if (Vector3.Distance(transform.position,playerTransform.posisiton)<playerMovementScript.distToPickUpGun && Input.GetKeyDown(KeyCode.E)&& playerMovementScript.waitFrameForSwitchGuns <= 0)
        {
            Debug.Log("Switch Guns");
            playerMovementScript.currentGun.GetComponent(GunScript).beingHeld = false;
            playerMovementScript.currentGun.GetComponent(GunScript).countToThrow = 2;
            playerMovementScript.currentGun = gameObject;
            beingHeld = true;
            targetYRotation = cameraObject.GetComponent(MouseLookScript).yRotation - 180;
            playerMovementScript.waitForSwitchGuns = 2;
        }
    }
}
[CODE]
I think I've spent more effort making this question than I think I have on anything else haha