these buttons are required in project input settings Forward Back Left Right Run Jump LookAround ToggleCrouch Mouse X Mouse Y attach to a capsule and set camera that is its child in the inspector Code (CSharp): using UnityEngine; using System.Collections; [RequireComponent(typeof(CapsuleCollider))] [RequireComponent(typeof(Rigidbody))] public class Rbctrl : MonoBehaviour { CapsuleCollider capsCollider; float crouchHeight,standHeight; Rigidbody rb; public Transform cam; public bool invertY; public float acceleration=6,deceleration=6,maxForwardSpeed=22,maxBackSpeed=18,maxStrafeSpeed=18,runModifier=18,crouchModifier=.6f, rotSpeed=4,minRotX=-90,maxRotX=90,minRotY=-90,maxRotY=90, rigidbodyDrag=5, speedMultiplierX=1,speedMultiplierZ=1, minJumpPower=9,maxJumpPower=9, jumpMultiplierX=.01f,jumpMultiplierY=.6f,jumpMultiplierZ=.01f, groundCheckDistance = .1f, stickToGroundHelperDistance=.05f, camBobX=.006f,camBobY=.008f,camBobZ=0,camReturnSpeed=.04f, playStepSoundAmount=666; public AudioClip[] stepSounds; public AudioClip[] jumpSounds; public AudioClip[] landSounds; AudioSource stepSourceA,stepSourceB,jumpSource,landSource; float currentAcceleration,currentDeceleration,currentMaxForwardSpeed,currentMaxBackSpeed,currentMaxStrafeSpeed,currentRunModifier, currentSpeedZ,currentSpeedX,speedBoost, rotationY, jumpPower,jumpZ,jumpX, addedJumpX,addedJumpZ, stepSoundAmount,stepVolume, camRotX,camRotY,previousCamRotX, camX,camY,camZ,camBobSpeed, n0,n1,combinedSpeeds,camSlerpAmount; int randomStepSoundIndex,lastStepIndex,randomLandSoundIndex,randomJumpSoundIndex; bool grounded,lookingAround,stepToggle,crouching,jumping; Quaternion camStartRot; Vector3 camTargetPosLocal,camStandTargetPos,camCrouchTargetPos; void Start () { capsCollider=GetComponent<CapsuleCollider>(); PhysicMaterial mat=new PhysicMaterial(); mat.dynamicFriction=0; mat.staticFriction=1; capsCollider.material=mat; rb = GetComponent<Rigidbody>(); rb.constraints=RigidbodyConstraints.FreezeRotation; rb.collisionDetectionMode=CollisionDetectionMode.ContinuousDynamic; crouchHeight=capsCollider.bounds.size.y*.66f; standHeight=capsCollider.bounds.size.y; camStandTargetPos=cam.localPosition; camCrouchTargetPos=new Vector3(camStandTargetPos.x,camStandTargetPos.y*.6f,camStandTargetPos.z); camTargetPosLocal=camStandTargetPos; camY=camTargetPosLocal.y; camX=camTargetPosLocal.x; camZ=camTargetPosLocal.z; camBobSpeed=(camBobX+camBobY+camBobZ)*1.1f; currentAcceleration= acceleration; currentDeceleration=deceleration; currentMaxForwardSpeed =maxForwardSpeed; currentMaxStrafeSpeed =maxStrafeSpeed; currentMaxBackSpeed= maxBackSpeed; currentRunModifier= runModifier; n0 = (maxStrafeSpeed+maxBackSpeed+maxForwardSpeed)/3; n1=n0+runModifier; stepSourceA=gameObject.AddComponent<AudioSource>(); stepSourceB=gameObject.AddComponent<AudioSource>(); jumpSource=gameObject.AddComponent<AudioSource>(); landSource=gameObject.AddComponent<AudioSource>(); } void Update() { if(Input.GetButtonDown ("ToggleCrouch")) { crouching=!crouching; if(crouching) { capsCollider.height=crouchHeight; camTargetPosLocal=camCrouchTargetPos; camX=camTargetPosLocal.x; camY=camTargetPosLocal.y; camZ=camTargetPosLocal.z; currentAcceleration*=crouchModifier; currentDeceleration*=crouchModifier; currentMaxBackSpeed*=crouchModifier; currentMaxForwardSpeed*=crouchModifier; currentMaxStrafeSpeed*=crouchModifier; currentRunModifier*=crouchModifier; } else { capsCollider.height=standHeight; camTargetPosLocal=camStandTargetPos; camX=camTargetPosLocal.x; camY=camTargetPosLocal.y; camZ=camTargetPosLocal.z; currentAcceleration=acceleration; currentDeceleration=deceleration; currentMaxBackSpeed=maxBackSpeed; currentMaxForwardSpeed=maxForwardSpeed; currentMaxStrafeSpeed=maxStrafeSpeed; currentRunModifier=runModifier; } } if(!lookingAround) { if(invertY) { camRotX += Input.GetAxisRaw ("Mouse Y")*rotSpeed; } else { camRotX -= Input.GetAxisRaw ("Mouse Y")*rotSpeed; } camRotX = Mathf.Clamp (camRotX, minRotX,maxRotX); cam.localRotation=Quaternion.Euler (camRotX,0,0); if(Input.GetButtonDown ("LookAround")) { previousCamRotX=camRotX; lookingAround=true; cam.localPosition=camTargetPosLocal; } } else { if(Input.GetButtonUp ("LookAround")) { camStartRot = cam.localRotation; StartCoroutine ("ReturnCamRot"); } camRotY+=Input.GetAxisRaw ("Mouse X")*rotSpeed; camRotY = Mathf.Clamp (camRotY,minRotY,maxRotY); if(invertY) { camRotX += Input.GetAxisRaw ("Mouse Y")*rotSpeed; } else { camRotX -= Input.GetAxisRaw ("Mouse Y")*rotSpeed; } camRotX = Mathf.Clamp (camRotX, minRotX,maxRotX); cam.localRotation=Quaternion.Euler (camRotX,camRotY,0); } if(Input.GetButton ("Jump")) { jumpPower+=currentAcceleration; if(Input.GetButton ("Forward")) jumpZ+=currentAcceleration; if(Input.GetButton ("Back")) jumpZ-=currentAcceleration; if(Input.GetButton ("Left")) jumpX-=currentAcceleration; if(Input.GetButton ("Right")) jumpX+=currentAcceleration; } if(Input.GetButtonUp ("Forward")) if(!Input.GetButton ("Back")) StartCoroutine ("SlowDownZ"); if(Input.GetButtonUp ("Back")) if(!Input.GetButton ("Forward")) StartCoroutine ("SlowDownZ"); if(Input.GetButtonUp ("Left")) if(!Input.GetButton ("Right")) StartCoroutine ("SlowDownX"); if(Input.GetButtonUp ("Right")) if(!Input.GetButton ("Left")) StartCoroutine ("SlowDownX"); if(Input.GetButtonUp ("Jump")) { if(grounded) { jumpZ = Mathf.Clamp (jumpZ,-maxJumpPower,maxJumpPower); jumpX = Mathf.Clamp (jumpX,-maxJumpPower,maxJumpPower); addedJumpX = jumpX + currentSpeedX; addedJumpZ = jumpZ + currentSpeedZ; jumpPower = Mathf.Clamp (jumpPower,minJumpPower,maxJumpPower); rb.AddRelativeForce (addedJumpX*jumpMultiplierX, jumpPower*jumpMultiplierY,addedJumpZ*jumpMultiplierZ,ForceMode.Impulse); if(jumpSounds.Length>0) { randomJumpSoundIndex=Random.Range (0,jumpSounds.Length); jumpSource.clip=jumpSounds[randomJumpSoundIndex]; jumpSource.volume=Random.Range (.5f,1f); jumpSource.Play (); } stepSoundAmount=0; StopCoroutine ("SlowDownX"); StopCoroutine ("SlowDownZ"); currentSpeedZ=0; currentSpeedX=0; jumping=true; } jumpPower = 0; jumpX = 0; jumpZ = 0; } if(grounded) { rotationY=Input.GetAxis ("Mouse X"); if(Input.GetButtonDown ("Forward") || Input.GetButtonDown ("Back")) { StopCoroutine ("SlowDownZ"); } if(Input.GetButtonDown ("Left") || Input.GetButtonDown ("Right")) { StopCoroutine ("SlowDownX"); } if(Input.GetButton ("Forward")) { currentSpeedZ+=currentAcceleration; } if(Input.GetButton ("Back")) { currentSpeedZ-=currentAcceleration; } if(Input.GetButton ("Left")) { currentSpeedX-=currentAcceleration; } if(Input.GetButton ("Right")) { currentSpeedX+=currentAcceleration; } if(Input.GetButton ("Run")) { speedBoost+=currentAcceleration; } else { speedBoost-=currentDeceleration; } speedBoost = Mathf.Clamp (speedBoost,0,runModifier); currentSpeedZ = Mathf.Clamp (currentSpeedZ,-currentMaxBackSpeed-speedBoost,currentMaxForwardSpeed+speedBoost); currentSpeedX = Mathf.Clamp (currentSpeedX,-currentMaxStrafeSpeed-speedBoost,currentMaxStrafeSpeed+speedBoost); } } IEnumerator SlowDownZ() { while(true) { currentSpeedZ+=currentSpeedZ>0 ? -deceleration:deceleration; if(Mathf.Abs (currentSpeedZ)<=deceleration) { currentSpeedZ=0; yield break; } else { yield return null; } } } IEnumerator SlowDownX() { while(true) { currentSpeedX+=currentSpeedX>0 ? -deceleration:deceleration; if(Mathf.Abs (currentSpeedX)<=deceleration) { currentSpeedX=0; yield break; } else { yield return null; } } } IEnumerator ReturnCamRot() { while(true) { camSlerpAmount+=camReturnSpeed; cam.localRotation = Quaternion.Slerp (camStartRot,Quaternion.Euler (previousCamRotX,0,0),camSlerpAmount); if(camSlerpAmount>.99f) { camSlerpAmount = 0; camRotY = 0; camRotX=previousCamRotX; cam.localRotation = Quaternion.Euler (camRotX,0,0); cam.localPosition=camTargetPosLocal; camY=camTargetPosLocal.y; camX=camTargetPosLocal.x; camZ=camTargetPosLocal.z; lookingAround=false; yield break; } yield return null; } } Quaternion deltaRotation; void FixedUpdate() { GroundCheck(); if(grounded) { rb.AddRelativeForce (currentSpeedX*speedMultiplierX,0,currentSpeedZ*speedMultiplierZ); if(!lookingAround) { deltaRotation = Quaternion.Euler(new Vector3(0,rotationY*rotSpeed,0)); transform.rotation=transform.rotation*deltaRotation; } if(currentSpeedX==0&¤tSpeedZ==0) { cam.localPosition=Vector3.MoveTowards (cam.localPosition,camTargetPosLocal,camBobSpeed); } combinedSpeeds=Mathf.Abs (currentSpeedZ) + Mathf.Abs (currentSpeedX); if(currentSpeedX != 0 && currentSpeedZ != 0) { stepSoundAmount+=combinedSpeeds*.5f* Mathf.Clamp ( Mathf.Abs (transform.InverseTransformDirection (rb.velocity).z)+ Mathf.Abs (transform.InverseTransformDirection (rb.velocity).x),0,1) ; } else { stepSoundAmount+=combinedSpeeds* Mathf.Clamp ( Mathf.Abs (transform.InverseTransformDirection (rb.velocity).z)+ Mathf.Abs (transform.InverseTransformDirection (rb.velocity).x),0,1) ; } if(!lookingAround) { if(stepSoundAmount>playStepSoundAmount*.5f) { camY-=camBobY; camZ+=camBobZ; camX += stepToggle ? -camBobX : camBobX; cam.localPosition=Vector3.MoveTowards (cam.localPosition,new Vector3(camX,camY,camZ),camBobSpeed* Mathf.Clamp ( Mathf.Abs (transform.InverseTransformDirection (rb.velocity).z)+ Mathf.Abs (transform.InverseTransformDirection (rb.velocity).x),0,1)); } else if(stepSoundAmount>playStepSoundAmount*.2f) { cam.localPosition=Vector3.MoveTowards (cam.localPosition,camTargetPosLocal,camBobSpeed*1.45f); } } if(stepSoundAmount>playStepSoundAmount) { stepToggle=!stepToggle; camY=camTargetPosLocal.y; camX=camTargetPosLocal.x; camZ=camTargetPosLocal.z; if(stepSounds.Length>0) { if(stepSounds.Length>1) { for(int i=0;i<Mathf.Infinity;i++) { randomStepSoundIndex=Random.Range (0,stepSounds.Length); if(randomStepSoundIndex!=lastStepIndex) break; } } if(currentSpeedX != 0 && currentSpeedZ != 0) { stepVolume = ((float)Mathf.Abs (currentSpeedX)/n1+(float)Mathf.Abs (currentSpeedZ)/n1)*.5f; } else { stepVolume = ((float)Mathf.Abs (currentSpeedX)/n1+(float)Mathf.Abs (currentSpeedZ)/n1); } stepVolume=Mathf.Clamp (stepVolume,0,1); if(stepToggle) { stepSourceA.clip=stepSounds[randomStepSoundIndex]; stepSourceA.volume=stepVolume; stepSourceA.Play (); } else { stepSourceB.clip=stepSounds[randomStepSoundIndex]; stepSourceB.volume=stepVolume; stepSourceB.Play (); } lastStepIndex=randomStepSoundIndex; } stepSoundAmount=0; } } StickToGroundHelper (); } RaycastHit hitInfo; bool previouslyGrounded; void GroundCheck() { if (Physics.SphereCast(transform.position, capsCollider.radius-.01f, Vector3.down, out hitInfo, ((capsCollider.height/2f) - capsCollider.radius) + groundCheckDistance)) { rb.drag=rigidbodyDrag; grounded = true; if(!previouslyGrounded&&jumping) { if(landSounds.Length>0) { if(!landSource.isPlaying) { randomLandSoundIndex=Random.Range (0,landSounds.Length); landSource.clip=landSounds[randomLandSoundIndex]; landSource.volume=Random.Range (.5f,1f); landSource.Play (); } } jumping=false; } } else { rb.drag=0; grounded = false; } previouslyGrounded=grounded; } void StickToGroundHelper() { if (Physics.SphereCast(transform.position, capsCollider.radius-.01f, Vector3.down, out hitInfo, ((capsCollider.height/2f) - capsCollider.radius) + stickToGroundHelperDistance)) { if (Mathf.Abs(Vector3.Angle(hitInfo.normal, Vector3.up)) < 85f) { rb.velocity = Vector3.ProjectOnPlane(rb.velocity, hitInfo.normal); } } } }
How about a description as to what this is, how it works, why you posted it here (and edited it 6 months later). What's up?