Here’s the full script (less than 20 lines) of my pick up script:
public void Update() {
//"detectedObject" is when an object has entered a trigger. This trigger is a child of the main camera, placed
//directly in front of the camera.
if (Input.GetMouseButtonDown(0) && this.detectedObject)
this.pick = true;
else if (Input.GetMouseButtonUp(0))
this.pick = false;
//"pickedObjects" is a List of Transforms that keeps track of how many objects that are picked.
//First object will always be picked regardless.
if (this.pick && this.pickedObjects.Count > 0) {
this.target = this.pickedObjects[0];
if (this.oldParent == null) {
//"oldParent" keeps track of the picked object's parent. It is used for restoring the picked object's parent
//when the object is released from the hands of the player.
this.oldParent = this.target.parent;
//"pickRegion" is the SphereCollider trigger.
this.target.parent = this.pickRegion.transform;
}
}
else if (!this.pick && this.target != null) {
this.target.parent = this.oldParent;
this.oldParent = null;
this.target = null;
//Clears all picked objects inside the trigger.
this.pickedObjects.Clear();
}
}
When you pick up a Rigidbody object, the parent of the object is set to the child of the main camera. This mean, when the main camera is rotating via the mouse, the child of the main camera follows the rotation, and in return, the Rigidbody object follows with the child, with the benefit of having fixed local transforms for the Rigidbody object.
The main problem is the useGravity flag that the Rigidbody object has. Currently, if the player has picked up the object, the useGravity flag is turned off, but the Rigidbody object will “float away” when it hits a wall while being picked up by the player. If the player lets go, the useGravity flag is turned on, and everything is normal.
I want to prevent the Rigidbody object from “floating away” and stay put in the hands of the player (or just stay put in front of the main camera). That includes after hitting the wall, the Rigidbody object doesn’t float away.
Does anyone know how to stop floating away? Thanks in advance.
I kind of feel that I’m working against the physics engine, by arbitrarily setting the picked up object’s position in the world. Maybe there’s a way to go around this, so instead of working against the physics engine, I can work along the physics engine.
With that in mind, I am wondering if it’s a good idea to use a Spring Joint as a connection from the hands of the player in the world, to the object that is picked up?
The more I’m thinking about this, the more I feel it may be plausible.
I’m about to work on this, but in the meantime, what would you think on this? And what other ideas do you know that can be used to work well with picking up physical objects in the scene?
Thats pretty much how all carrying of objects are done in HalfLife 2, with a springjoint connected to the camera.
If you turn your object kinematic it will likely disappear into walls and other objects as you move it around.
Faced a similar problem when I had a game in UE4 also involving moving objects about. Having an object phase through obstacles and become unable to get them was mistake number 1 when I did the equivalent of setting the object to kinematic in UE4. Had to use this thing called a physicsHandler to pretty much do what was done in HalfLife2, though not sure if spring is the Unity equivalent.
Already tried increasing the picked up object’s Rigidbody’s drag and angular drag values very high, but that ended up creating weird physics where the object would slowly rotate around the hand when the player moves around.
If there’s a way to set the max “length” of the spring to 0f, therefore disabling the spring’s elasticity, that would be wonderful.
for some reason my player instantly flies up when I press space. this is my code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class player : MonoBehaviour
{
bool Jump;
bool Foreward;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Jump = true;
}
if (Input.GetKeyDown(KeyCode.W))
{
Foreward = true;
}
}
// FixedUpdate is called once per physics update
void FixedUpdate()
{
if (Jump == true)
{
GetComponent<Rigidbody>().AddForce(Vector3.up, ForceMode.VelocityChange);
}
if (Foreward == true)
{
GetComponent<Rigidbody>().AddForce(Vector3.forward, ForceMode.VelocityChange);
}
} }
jump never gets setted false so it will jump infinite do this if (Input.GetKeyDown(KeyCode.Space)) { GetComponent<Rigidbody>().AddForce(Vector3.up, ForceMode.VelocityChange); }