Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

why does holding objects move character (not desired effect)

Discussion in 'Scripting' started by superskeet, Feb 4, 2021.

  1. superskeet

    superskeet

    Joined:
    Feb 4, 2021
    Posts:
    8
    i am using a couple scripts to pick up a object and hold it infront of the player . works great except when i look slightly down/the closer the object gets to player i start moving backwards the more i look down the faster i go . if i very quickly look down it shoots my character in the sky like a rocket. i will attach screenshots and code. thanks for any help im sure this is a simple issue im over looking.


    simplegrabsystem.cs
    Code (CSharp):
    1. using UnityEngine;
    2. /// <summary>
    3. /// Simple example of Grabbing system.
    4. /// </summary>
    5. public class SimpleGrabSystem : MonoBehaviour
    6. {
    7.     // Reference to the character camera.
    8.     [SerializeField]
    9.     private Camera characterCamera;
    10.     // Reference to the slot for holding picked item.
    11.     [SerializeField]
    12.     private Transform slot;
    13.     // Reference to the currently held item.
    14.     private PickableItem pickedItem;
    15.     /// <summary>
    16.     /// Method called very frame.
    17.     /// </summary>
    18.     private void Update()
    19.     {
    20.         // Execute logic only on button pressed
    21.         if (Input.GetButtonDown("Fire1"))
    22.         {
    23.             // Check if player picked some item already
    24.             if (pickedItem)
    25.             {
    26.                 // If yes, drop picked item
    27.                 DropItem(pickedItem);
    28.             }
    29.             else
    30.             {
    31.                 // If no, try to pick item in front of the player
    32.                 // Create ray from center of the screen
    33.                 var ray = characterCamera.ViewportPointToRay(Vector3.one * 0.5f);
    34.                 RaycastHit hit;
    35.                 // Shot ray to find object to pick
    36.                 if (Physics.Raycast(ray, out hit, 1.5f))
    37.                 {
    38.                     // Check if object is pickable
    39.                     var pickable = hit.transform.GetComponent<PickableItem>();
    40.                     // If object has PickableItem class
    41.                     if (pickable)
    42.                     {
    43.                         // Pick it
    44.                         PickItem(pickable);
    45.                     }
    46.                 }
    47.             }
    48.         }
    49.     }
    50.     /// <summary>
    51.     /// Method for picking up item.
    52.     /// </summary>
    53.     /// <param name="item">Item.</param>
    54.     private void PickItem(PickableItem item)
    55.     {
    56.         // Assign reference
    57.         pickedItem = item;
    58.         // Disable rigidbody and reset velocities
    59.         item.Rb.isKinematic = true;
    60.        // item.Rb.velocity = Vector3.zero;
    61.       // item.Rb.angularVelocity = Vector3.zero;
    62.         // Set Slot as a parent
    63.         item.transform.SetParent(slot);
    64.         // Reset position and rotation
    65.         item.transform.localPosition = Vector3.zero;
    66.         item.transform.localEulerAngles = Vector3.zero;
    67.     }
    68.     /// <summary>
    69.     /// Method for dropping item.
    70.     /// </summary>
    71.     /// <param name="item">Item.</param>
    72.     private void DropItem(PickableItem item)
    73.     {
    74.         // Remove reference
    75.         pickedItem = null;
    76.         // Remove parent
    77.         item.transform.SetParent(null);
    78.         // Enable rigidbody
    79.         item.Rb.isKinematic = false;
    80.         // Add force to throw item a little bit
    81.         item.Rb.AddForce(item.transform.forward * 2, ForceMode.VelocityChange);
    82.     }
    83. }



    pickableitem
    Code (CSharp):
    1. using UnityEngine;
    2. /// <summary>
    3. /// Simple example of Grabbing system.
    4. /// </summary>
    5. public class SimpleGrabSystem : MonoBehaviour
    6. {
    7.     // Reference to the character camera.
    8.     [SerializeField]
    9.     private Camera characterCamera;
    10.     // Reference to the slot for holding picked item.
    11.     [SerializeField]
    12.     private Transform slot;
    13.     // Reference to the currently held item.
    14.     private PickableItem pickedItem;
    15.     /// <summary>
    16.     /// Method called very frame.
    17.     /// </summary>
    18.     private void Update()
    19.     {
    20.         // Execute logic only on button pressed
    21.         if (Input.GetButtonDown("Fire1"))
    22.         {
    23.             // Check if player picked some item already
    24.             if (pickedItem)
    25.             {
    26.                 // If yes, drop picked item
    27.                 DropItem(pickedItem);
    28.             }
    29.             else
    30.             {
    31.                 // If no, try to pick item in front of the player
    32.                 // Create ray from center of the screen
    33.                 var ray = characterCamera.ViewportPointToRay(Vector3.one * 0.5f);
    34.                 RaycastHit hit;
    35.                 // Shot ray to find object to pick
    36.                 if (Physics.Raycast(ray, out hit, 1.5f))
    37.                 {
    38.                     // Check if object is pickable
    39.                     var pickable = hit.transform.GetComponent<PickableItem>();
    40.                     // If object has PickableItem class
    41.                     if (pickable)
    42.                     {
    43.                         // Pick it
    44.                         PickItem(pickable);
    45.                     }
    46.                 }
    47.             }
    48.         }
    49.     }
    50.     /// <summary>
    51.     /// Method for picking up item.
    52.     /// </summary>
    53.     /// <param name="item">Item.</param>
    54.     private void PickItem(PickableItem item)
    55.     {
    56.         // Assign reference
    57.         pickedItem = item;
    58.         // Disable rigidbody and reset velocities
    59.         item.Rb.isKinematic = true;
    60.        // item.Rb.velocity = Vector3.zero;
    61.       // item.Rb.angularVelocity = Vector3.zero;
    62.         // Set Slot as a parent
    63.         item.transform.SetParent(slot);
    64.         // Reset position and rotation
    65.         item.transform.localPosition = Vector3.zero;
    66.         item.transform.localEulerAngles = Vector3.zero;
    67.     }
    68.     /// <summary>
    69.     /// Method for dropping item.
    70.     /// </summary>
    71.     /// <param name="item">Item.</param>
    72.     private void DropItem(PickableItem item)
    73.     {
    74.         // Remove reference
    75.         pickedItem = null;
    76.         // Remove parent
    77.         item.transform.SetParent(null);
    78.         // Enable rigidbody
    79.         item.Rb.isKinematic = false;
    80.         // Add force to throw item a little bit
    81.         item.Rb.AddForce(item.transform.forward * 2, ForceMode.VelocityChange);
    82.     }
    83. }
    screenshots of player info & item info/heirachy & me flying





     
  2. Omniglitch

    Omniglitch

    Joined:
    May 29, 2017
    Posts:
    37
    I think I know what's happening. When you look down the held object's Box Collider intersects with your character's Capsule Collider. The physics system then tries to de-penetrate the collision by pushing your character back out of the way.

    One way to solve it would be to disable the held object's collider when it's picked up (or make it kinematic), and re-enable it when the object is dropped.

    My preference is to make the player's collider kinematic all the time to avoid weird physics glitches, and manually handle collisions with the player using the OnCollisionEnter callback function.
     
    Owen-Reynolds likes this.
  3. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,920
    It doesn't "know" that you're holding the object. The game is basically ramming the held item in the player's face, which shoves the player backwards. Bending forward makes it worse since there's more intersection. It's been a while, but a solution is making it a child of the player. The physics system understands compound colliders that count as one thing. Or, turn off the held item's collider, or make sure it can't overlap, or do tricks with the layers so held items don't interact with players.
     
  4. superskeet

    superskeet

    Joined:
    Feb 4, 2021
    Posts:
    8
    out of the methods you suggest , which one would have a better outcome? i tried writing some code to disable the items mesh collider when its being held but no luck on getting the box to uncheck. a ghetto solution i found was put the grab slot far enough away from the camera that it cant intersect with player. but that just results in the item being to far away and clips through walls easier.
     
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,920
    Moving grabSlot to be a child of the player (the capsule) should work (but it's been a while since I played with this). Of course, it will count as part of the player while you move around (you'll stop when the held item hits something). The thing is, if you can't turn off a collider, you're still learning. This is all just messing around until you know enough to make something seriously.
     
    superskeet likes this.
  6. superskeet

    superskeet

    Joined:
    Feb 4, 2021
    Posts:
    8
    most definitely still learning , last coding i did was for a 317 revision of runecape private servers , so very limited java knowledge enough to mod that game.
     
  7. superskeet

    superskeet

    Joined:
    Feb 4, 2021
    Posts:
    8
    making the grab slot does remove the chance of it accelerating your character but only because it locks the item in place. so to achieve the effect i want im gonna have to either mess with the colliders or just have a line of code disable the mesh collider when item is being held. just like the way the item looks when it moves with the camera more natural.
     
  8. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,920
    If grabSlot is a child of the player, it's locked int place _on the player_. When the player moves and turns, it will. You can try it without code -- hand-place the grabbed object into the player-capsule, then move and turn the player.