Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

ETeeskiTutorials FPS1.42 Inverse Kinematic Arm Tutorial scripts and project download.

Discussion in 'Community Learning & Teaching' started by eteeski, Jun 10, 2012.

  1. eteeski

    eteeski

    Joined:
    Feb 2, 2010
    Posts:
    476
    click here to see my tutorial on making an Inverse Kinematic Arm

    Here are the scripts created/modified in my tutorial, FPS1.42. Also, there is a zip file of the project free for download.

    Zip file of FPS1.42:
    http://www.mediafire.com/?qoio11zbwqmqqzx

    InverseKinematicArmScript:
    Code (csharp):
    1.  
    2. var target : Transform;
    3. var handTransform : Transform;
    4.  
    5. var shoulderTransform : Transform;
    6. var shoulderElbowPoint : Transform;
    7. var shoulderLength : float;
    8.  
    9. var wristTransform : Transform;
    10. var wristElbowPoint : Transform;
    11. var wristLength : float;
    12.  
    13. var elbowWeight : Transform;
    14.  
    15. var elbowZ : float;
    16. var distToTarget : float;
    17.  
    18. function Awake ()
    19. {
    20.     shoulderLength = Vector3.Distance( shoulderTransform.position, shoulderElbowPoint.position);
    21.     wristLength = Vector3.Distance( wristTransform.position, wristElbowPoint.position);
    22. }
    23.  
    24. function Update ()
    25. {
    26.     handTransform.rotation = target.rotation;
    27.     handTransform.position = wristTransform.position;
    28.     transform.LookAt(target, transform.position - elbowWeight.position);
    29.     distToTarget = Vector3.Distance(target.position, shoulderTransform.position);
    30.     elbowZ = (Mathf.Pow(distToTarget, 2) - Mathf.Pow(wristLength, 2) + Mathf.Pow(shoulderLength,2))/(distToTarget * 2);
    31.    
    32.     wristTransform.localPosition.z = Mathf.Clamp(distToTarget, 0, wristLength + shoulderLength);
    33.    
    34.     if (distToTarget < shoulderLength + wristLength  distToTarget > Mathf.Max(shoulderLength, wristLength) - Mathf.Min(shoulderLength, wristLength)){
    35.         shoulderTransform.localRotation = Quaternion.Euler(Mathf.Acos(elbowZ/shoulderLength) * Mathf.Rad2Deg, 0, 0);
    36.         wristTransform.localRotation = Quaternion.Euler( -(Mathf.Acos((distToTarget - elbowZ)/wristLength) * Mathf.Rad2Deg), 0, 0);}
    37.    
    38.     if (distToTarget >= shoulderLength + wristLength)
    39.     {
    40.         shoulderTransform.localRotation = Quaternion.Euler(0,0,0);
    41.         wristTransform.localRotation = Quaternion.Euler(0,0,0);
    42.     }
    43.     if (distToTarget <= Mathf.Max(shoulderLength, wristLength) - Mathf.Min(shoulderLength, wristLength))
    44.     {
    45.         shoulderTransform.localRotation = Quaternion.Euler(0,0,0);
    46.         wristTransform.localRotation = Quaternion.Euler(180,0,0);
    47.     }
    48.  
    49. }
    50.  
    EnemyBodyScript:
    Code (csharp):
    1.  
    2. var moveDamp : float = 0.1;
    3. var parentToFollow : Transform;
    4. var parentLastPos : Vector3;
    5. var targetRotation : Quaternion;
    6. var turnSpeed : float = 10;
    7.  
    8. var velocityX : float;
    9. var velocityZ : float;
    10.  
    11. var parentScript : EnemyMovementScript;
    12. var walkAnimationString : String;
    13. var runAnimationString : String;
    14.  
    15. var enemyHealth : float = 1;
    16. var rigidbodies : Rigidbody[];
    17. var armParentScripts : InverseKinematicArmScript[];
    18.  
    19. function Awake ()
    20. {
    21.     parentScript = transform.parent.GetComponent(EnemyMovementScript);
    22.     animation.wrapMode = WrapMode.Loop;
    23.     parentToFollow = transform.parent;
    24.     transform.parent = null;
    25. }
    26.  
    27. function Update ()
    28. {
    29.     transform.position.x = Mathf.SmoothDamp(transform.position.x, parentToFollow.position.x, velocityX, moveDamp);
    30.     transform.position.z = Mathf.SmoothDamp(transform.position.z, parentToFollow.position.z, velocityZ, moveDamp);
    31.    
    32.     var tempParentCurrentPos : Vector3 = parentToFollow.position;
    33.     var tempParentLastPos : Vector3 = parentLastPos;
    34.     tempParentCurrentPos.y = 0;
    35.     tempParentLastPos.y = 0;
    36.    
    37.     targetRotation = Quaternion.LookRotation(tempParentCurrentPos - tempParentLastPos);
    38.     parentLastPos = parentToFollow.position;
    39.    
    40.     transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
    41.    
    42.     var hits : RaycastHit[];
    43.     hits = Physics.RaycastAll(Ray(transform.position + Vector3(0,100,0), Vector3.up * -1));
    44.     for (var i : int = 0; i < hits.length; i++)
    45.     {
    46.         var hit : RaycastHit = hits[i];
    47.         if (hit.transform.gameObject == parentToFollow.gameObject.GetComponent(EnemyMovementScript).currentCell)
    48.             transform.position.y = hit.point.y;
    49.     }
    50.    
    51.     if (!animation.IsPlaying(walkAnimationString)  !parentScript.aware)
    52.         animation.Play(walkAnimationString);
    53.     if (!animation.IsPlaying(runAnimationString)  parentScript.aware)
    54.         animation.Play(runAnimationString);
    55.        
    56.     if (enemyHealth <= 0)
    57.     {
    58.         for (var rigidbodyFor in rigidbodies)
    59.             rigidbodyFor.isKinematic = false;
    60.        
    61.         for (var armParentScriptFor in armParentScripts)
    62.             armParentScriptFor.enabled = false;
    63.        
    64.         animation.enabled = false;
    65.         parentScript.enabled = false;
    66.         enabled = false;
    67.     }
    68. }
    69.  
    (The only thing modified in the PlayerMovementScript was fixing the problem of sliding down slopes.)
    PlayerMovementScript:
    Code (csharp):
    1.  
    2. var currentGun : GameObject;
    3. var distToPickUpGun : float = 6;
    4. var throwGunUpForce : float = 100;
    5. var throwGunForwardForce : float = 300;
    6. var waitFrameForSwitchGuns : int = -1;
    7.  
    8. var walkAcceleration : float = 5;
    9. var walkAccelAirRacio : float = 0.1;
    10. var walkDeacceleration : float = 5;
    11. @HideInInspector
    12. var walkDeaccelerationVolx : float;
    13. @HideInInspector
    14. var walkDeaccelerationVolz : float;
    15.  
    16. var cameraObject : GameObject;
    17. var maxWalkSpeed : float = 20;
    18. @HideInInspector
    19. var horizontalMovement : Vector2;
    20.  
    21. var jumpVelocity : float = 20;
    22. @HideInInspector
    23. var grounded : boolean = false;
    24. var maxSlope : float = 60;
    25.  
    26. var crouchRacio : float = 0.3;
    27. var transitionToCrouchSec : float = 0.2;
    28. var crouchingVelocity : float;
    29. var currentCrouchRacio : float = 1;
    30. var originalLocalScaleY : float;
    31. var crouchLocalScaleY : float;
    32. var collisionDetectionSphere : GameObject;
    33.  
    34. @HideInInspector
    35. var waitToPickupAmmo : float = 0;
    36.  
    37. var currentCell : GameObject;
    38.  
    39. function Awake ()
    40. {
    41.     currentCrouchRacio = 1;
    42.     originalLocalScaleY = transform.localScale.y;
    43.     crouchLocalScaleY = transform.localScale.y * crouchRacio;
    44. }
    45.  
    46. function LateUpdate ()
    47. {
    48.     if (grounded)
    49.         rigidbody.useGravity = false;
    50.     else
    51.         rigidbody.useGravity = true;
    52.    
    53.     waitFrameForSwitchGuns -= 1;
    54.     waitToPickupAmmo -= Time.deltaTime;
    55.    
    56.     transform.localScale.y = Mathf.Lerp(crouchLocalScaleY, originalLocalScaleY, currentCrouchRacio);
    57.     if (Input.GetButton("Crouch"))
    58.         currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 0, crouchingVelocity, transitionToCrouchSec);
    59.     if (Input.GetButton("Crouch") == false  collisionDetectionSphere.GetComponent(CollsionDetectionSphereScript).collisionDetected == false)
    60.         currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 1, crouchingVelocity, transitionToCrouchSec);
    61.    
    62.     horizontalMovement = Vector2(rigidbody.velocity.x, rigidbody.velocity.z);
    63.     if (horizontalMovement.magnitude > maxWalkSpeed)
    64.     {
    65.         horizontalMovement = horizontalMovement.normalized;
    66.         horizontalMovement *= maxWalkSpeed;    
    67.     }
    68.    
    69.     rigidbody.velocity.x = horizontalMovement.x;
    70.     rigidbody.velocity.z = horizontalMovement.y;
    71.    
    72.     if (grounded){
    73.         rigidbody.velocity.x = Mathf.SmoothDamp(rigidbody.velocity.x, 0, walkDeaccelerationVolx, walkDeacceleration);
    74.         rigidbody.velocity.z = Mathf.SmoothDamp(rigidbody.velocity.z, 0, walkDeaccelerationVolz, walkDeacceleration);}
    75.    
    76.     transform.rotation = Quaternion.Euler(0, cameraObject.GetComponent(MouseLookScript).currentYRotation, 0);
    77.    
    78.     /*if (grounded)
    79.         rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * Time.deltaTime, 0, Input.GetAxis("Vertical") * walkAcceleration * Time.deltaTime);
    80.     else
    81.         rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * walkAccelAirRacio * Time.deltaTime, 0, Input.GetAxis("Vertical") * walkAcceleration * walkAccelAirRacio * Time.deltaTime);
    82.             */
    83.     if (Input.GetButtonDown("Jump")  grounded)
    84.         rigidbody.AddForce(0,jumpVelocity,0);
    85. }
    86.  
    87. function FixedUpdate ()
    88. {
    89.     if (grounded)
    90.         rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration, 0, Input.GetAxis("Vertical") * walkAcceleration);
    91.     else
    92.         rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * walkAccelAirRacio, 0, Input.GetAxis("Vertical") * walkAcceleration * walkAccelAirRacio);
    93. }
    94.  
    95. function OnCollisionStay (collision : Collision)
    96. {
    97.     for (var contact : ContactPoint in collision.contacts)
    98.     {
    99.         if (Vector3.Angle(contact.normal, Vector3.up) < maxSlope)
    100.             grounded = true;
    101.     }
    102. }
    103.  
    104. function OnCollisionExit ()
    105. {
    106.     grounded = false;
    107. }
    108.  
    109. function OnTriggerExit ()
    110. {
    111.     currentCell = null;
    112. }
    113.  
    114. function OnTriggerStay (hitTrigger : Collider)
    115. {
    116.     if (hitTrigger.tag == "AIpathCell")
    117.         currentCell = hitTrigger.gameObject;
    118.  
    119.     if (hitTrigger.transform.tag == "StairGoingUp")
    120.         if (!Input.GetButton("Jump")  Vector3.Angle(rigidbody.velocity, hitTrigger.transform.forward) < 90)
    121.             if (rigidbody.velocity.y > 0)
    122.                 rigidbody.velocity.y = 0;
    123.     if (hitTrigger.transform.tag == "StairGoingDown")
    124.         if (!Input.GetButton("Jump")  Vector3.Angle(rigidbody.velocity, hitTrigger.transform.forward) < 90)
    125.             rigidbody.AddForce(0,-100,0);
    126.  
    127.  
    128.     var current : GunScript = null;
    129.     if (currentGun)
    130.         current = currentGun.GetComponent(GunScript);
    131.     var ammo : AmmoPickupScript = null;
    132.     var gun : GunScript = null;
    133.     if (hitTrigger.tag == "AmmoPickup"  waitToPickupAmmo <= 0)
    134.     {
    135.         ammo = hitTrigger.gameObject.GetComponent(AmmoPickupScript);
    136.         if (current.currentExtraAmmo < current.maxExtraAmmo)
    137.         {
    138.             if (ammo.fromGun)
    139.             {
    140.                 gun = ammo.gun.GetComponent(GunScript);
    141.                 if (gun.currentExtraAmmo > 0  gun.ammoType == current.ammoType  ammo.gun != currentGun)
    142.                 {
    143.                     if (gun.currentExtraAmmo >= current.maxExtraAmmo - current.currentExtraAmmo)
    144.                     {
    145.                         gun.currentExtraAmmo -= current.maxExtraAmmo - current.currentExtraAmmo;
    146.                         current.currentExtraAmmo = current.maxExtraAmmo;
    147.                     }
    148.                     if (gun.currentExtraAmmo < current.maxExtraAmmo - current.currentExtraAmmo)
    149.                     {
    150.                         current.currentExtraAmmo += gun.currentExtraAmmo;
    151.                         gun.currentExtraAmmo = 0;
    152.                     }
    153.                     if (ammo.pickupSound)
    154.                         ammo.gameObject.GetComponent(AudioSource).Play();
    155.                 }
    156.             }
    157.             if (!ammo.fromGun)
    158.             {
    159.                 if (current.ammoType == ammo.ammoType || ammo.ammoType == -1)
    160.                 {
    161.                     if (ammo.ammoAmount > 0  !ammo.unlimitedAmmo)
    162.                     {
    163.                         if (ammo.ammoAmount >= current.maxExtraAmmo - current.currentExtraAmmo)
    164.                         {
    165.                             ammo.ammoAmount -= current.maxExtraAmmo - current.currentExtraAmmo;
    166.                             current.currentExtraAmmo = current.maxExtraAmmo;
    167.                         }
    168.                         if (ammo.ammoAmount < current.maxExtraAmmo - current.currentExtraAmmo)
    169.                         {
    170.                             current.currentExtraAmmo += gun.currentExtraAmmo;
    171.                             ammo.ammoAmount = 0;
    172.                         }
    173.                         if (ammo.pickupSound)
    174.                             ammo.gameObject.GetComponent(AudioSource).Play();
    175.                     }
    176.                     if (ammo.unlimitedAmmo)
    177.                     {
    178.                         current.currentExtraAmmo = current.maxExtraAmmo;
    179.                         if (ammo.pickupSound)
    180.                             ammo.gameObject.GetComponent(AudioSource).Play();
    181.                     }
    182.                 }
    183.             }
    184.         }
    185.     }
    186. }
    187.  
     
    Last edited: Jun 12, 2012
  2. Cybor Fifth

    Cybor Fifth

    Joined:
    Jun 10, 2012
    Posts:
    1
    Thanx a lot dude
     
  3. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    I have problem with downloading the .zip from mediafire. My computer says: "The .zip file is empty" and i can't open it :(
    Please help...
     
  4. eteeski

    eteeski

    Joined:
    Feb 2, 2010
    Posts:
    476
    are you on pc or mac?
     
  5. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
  6. eteeski

    eteeski

    Joined:
    Feb 2, 2010
    Posts:
    476
    ok, try it now. hopefully it works. i just re-uploaded it.
     
  7. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    Sorry...it still doesn't work :(
     
  8. eteeski

    eteeski

    Joined:
    Feb 2, 2010
    Posts:
    476
    hmm. at what point doesn't it work? are you able to get a zip file from mediafire? are you able to unzip it? do the files show up (such as the asset folder with all the scripts and materials and prefab files in it)? what does unity do when you try to load the project?

    the only thing i can suggest is getting the latest version of unity, or a different un-compression tool, or check your firewall settings.
     
  9. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    i can't open or extract because windows says: "The file is empty"
     
  10. eteeski

    eteeski

    Joined:
    Feb 2, 2010
    Posts:
    476
    have you tried more than one un-compressor? i.e. winzip?
     
  11. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    I had tried it with WinRar, too... It doesn't work :( Can you please try to upload it to the forum?
     
  12. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    The problem is mediafire or my PC doesn't like mediafire...i tried to download another .zip from mediafire and had the same problem...
     
  13. eteeski

    eteeski

    Joined:
    Feb 2, 2010
    Posts:
    476
    i really wanted to upload it to the unity forums, but i guess my account ran out of space or something. pm me your email. I'll just send it to you.
     
  14. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    PM sent :) Thanks so much :D I love your tutorials
     
  15. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    Thanks for the mail :)

    I tried to make IK arms for the Player, too. But if i play the game the player walks without pressing any keys and the arms are behind the player. Can you please make tutorial on how to make IK arms for the player, too?

    Thanks a lot
    Buster
     
  16. eteeski

    eteeski

    Joined:
    Feb 2, 2010
    Posts:
    476
    did you turn the colliders off?
     
  17. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    the colliders of the arms? no...i'll try it
     
  18. BusterBlader

    BusterBlader

    Joined:
    Apr 23, 2012
    Posts:
    79
    Now he isn't walking without pressing keys but...the arms are at the wrong positions...at the moment i am playing with the pivots :) Hopefully i'll get it working :D
     
  19. nandasasmita

    nandasasmita

    Joined:
    Dec 12, 2013
    Posts:
    3
    Eteeski i have small glitch, when i shoot my enemy and die, the enemy is pushed too far, but the ragdoll is ok. it's because the bulletforce? i try change bulletforce to small number, still the enemy pushed back too far