Trying to fix obsolete code based around Spring Joints?
I have been attempting to find a way to control a paddle with a mouse for a simple game that has you bouncing a ball on a paddle. I am pretty new to programming and was trying to find anything that might be what I was looking for. I eventually stumbled across this code for pretty much exactly what I was looking for on Git Hub, but it was written in 2011 and uses a lot of obsolete methods. I added [System.Obsolete] lines which let it run, but I assume that it is not a good practice to leave it like that. The main problem is I just have no clue how this code works and can not figure out information on what these obsolete methods did or how to update them. I would really appreciate any help that I can get! Here is the code: using UnityEngine;
/// <summary>
/// Drag a rigidbody with the mouse using a spring joint.
/// </summary>
[RequireComponent(typeof(Rigidbody))]
public class DragRigidbody : MonoBehaviour
{
public float force = 600;
public float damping = 6;
Transform jointTrans;
float dragDepth;
[System.Obsolete]
void OnMouseDown()
{
HandleInputBegin(Input.mousePosition); // Obsolete
}
void OnMouseUp()
{
HandleInputEnd();
}
void OnMouseDrag()
{
HandleInput(Input.mousePosition);
}
[System.Obsolete]
public void HandleInputBegin(Vector3 screenPosition)
{
var ray = Camera.main.ScreenPointToRay(screenPosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Paddle"))
{
dragDepth = CameraPlane.CameraToPointDepth(Camera.main, hit.point);
jointTrans = AttachJoint(hit.rigidbody, hit.point); // Obsolete
}
}
}
public void HandleInput(Vector3 screenPosition)
{
if (jointTrans == null)
return;
var worldPos = Camera.main.ScreenToWorldPoint(screenPosition);
jointTrans.position = CameraPlane.ScreenToWorldPlanePoint(Camera.main, dragDepth, screenPosition);
}
public void HandleInputEnd()
{
Destroy(jointTrans.gameObject);
}
[System.Obsolete]
Transform AttachJoint(Rigidbody rb, Vector3 attachmentPosition)
{
GameObject go = new GameObject("Attachment Point");
go.hideFlags = HideFlags.HideInHierarchy;
go.transform.position = attachmentPosition;
var newRb = go.AddComponent<Rigidbody>();
newRb.isKinematic = true;
var joint = go.AddComponent<ConfigurableJoint>();
joint.connectedBody = rb;
joint.configuredInWorldSpace = true;
joint.xDrive = NewJointDrive(force, damping); // Obsolete
joint.yDrive = NewJointDrive(force, damping); // Obsolete
joint.zDrive = NewJointDrive(force, damping); // Obsolete
joint.slerpDrive = NewJointDrive(force, damping); // Obsolete
joint.rotationDriveMode = RotationDriveMode.Slerp;
return go.transform;
}
[System.Obsolete]
private JointDrive NewJointDrive(float force, float damping)
{
JointDrive drive = new JointDrive();
drive.mode = JointDriveMode.Position; // Obsolete
drive.positionSpring = force;
drive.positionDamper = damping;
drive.maximumForce = Mathf.Infinity;
return drive;
}
}
I commented beside every line that Visual Studios told me was Obsolete, hopefully that can help...
Answer by Camden9 · Sep 18, 2020 at 02:30 AM
I actually figured it out, if anyone is ever looking for this, this is the updated code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PaddleHandler : MonoBehaviour
{
// Summary
// Creates a configurable joint at the point on object that is clicked
// This allows the object to be moved and gives it the ability to interact with other objects with physics while being moved
// give objects that you would like to move this script and layer "Interactable"
float dragDepth;
Transform jointTrans;
// Variables for Adjusting the joint
[Header("Spring Joint Variables")]
[SerializeField] float force = 1000f;
[SerializeField] float damper = 10f;
[Space]
// Variables for Clamping Movement of object once grabbed, remove in HandleInput if you don't want this
[Header("Clamping Variables")]
[SerializeField] float horizontalClamp = 2f;
[SerializeField] float verticalClamp = 5f;
[Space]
// Variables for resetting Velocity
[Header("Resetting Velocity")]
bool letGo = true;
[SerializeField] float velocityDecreaseRate = .8f;
//Variables for resetting Rotation
[Header("Resetting Rotation")]
bool restoreRotation = false;
Quaternion originalRotation;
[SerializeField] float rotateSpeed = 8f;
// RigidBody
Rigidbody rb;
// Initializes Rigidbody
void Awake()
{
rb = GetComponent<Rigidbody>();
}
// Initialize standard rotation
private void Start()
{
originalRotation = transform.rotation;
}
// Fixed Update used for resetting velocity and rotation
void FixedUpdate()
{
ResetVelocity();
}
// Update used for resetting rotation
void Update()
{
Rotate();
}
// Method called when mouse is pressed
private void OnMouseDown()
{
HandleInputBegin(Input.mousePosition);
}
// Method called when mouse is dragged
private void OnMouseDrag()
{
HandleInput(Input.mousePosition);
}
// Method called when mouse is let go
private void OnMouseUp()
{
HandleInputEnd();
}
// Cast a ray where the mouse is and grab object
public void HandleInputBegin(Vector3 screenPosition)
{
var ray = Camera.main.ScreenPointToRay(screenPosition);
if (Physics.Raycast(ray, out RaycastHit hit))
{
if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Interactable"))
{
dragDepth = CameraPlane.CameraToPointDepth(Camera.main, hit.point);
jointTrans = AttachJoint(hit.rigidbody, hit.point);
}
}
letGo = false;
}
// Moves object with the mouse
public void HandleInput(Vector3 screenPosition)
{
if (jointTrans == null) return;
jointTrans.position = CameraPlane.ScreenToWorldPlanePoint(Camera.main, dragDepth, screenPosition);
ClampMovement(); // delete if you don't want clamped movement
}
// Destroys joint and returns object to normal roation
void HandleInputEnd()
{
Destroy(jointTrans.gameObject);
letGo = true;
restoreRotation = true;
}
// Clamps movement for z and y variables
private void ClampMovement()
{
Vector3 clampedPosition = jointTrans.position;
clampedPosition.z = Mathf.Clamp(clampedPosition.z, -horizontalClamp, horizontalClamp);
clampedPosition.y = Mathf.Clamp(clampedPosition.y, -verticalClamp, verticalClamp);
jointTrans.position = clampedPosition;
}
// Attaches joint and sets up basic configuration
Transform AttachJoint(Rigidbody rb, Vector3 attachmentPosition)
{
GameObject go = new GameObject("Attachment Point")
{
hideFlags = HideFlags.HideInHierarchy
};
go.transform.position = attachmentPosition;
var newRb = go.AddComponent<Rigidbody>();
newRb.isKinematic = true;
var joint = go.AddComponent<ConfigurableJoint>();
joint.connectedBody = rb;
joint.configuredInWorldSpace = true;
joint.xDrive = NewJointDrive(force, damper);
joint.yDrive = NewJointDrive(force, damper);
joint.zDrive = NewJointDrive(force, damper);
joint.slerpDrive = NewJointDrive(force, damper);
joint.rotationDriveMode = RotationDriveMode.Slerp;
return go.transform;
}
// Sets up more advanced configurations of joints
private JointDrive NewJointDrive(float force, float damping)
{
JointDrive drive = new JointDrive
{
positionSpring = force,
positionDamper = damping,
maximumForce = Mathf.Infinity
};
return drive;
}
// Begins rotation of pbject back to normal
void Rotate()
{
if (restoreRotation)
{
transform.rotation = Quaternion.Lerp(transform.rotation, originalRotation, Time.deltaTime * rotateSpeed);
if (transform.rotation == originalRotation)
restoreRotation = false;
}
}
// Resets Velocity and Angular Velocity of Rigidbody
void ResetVelocity()
{
if(rb.velocity != Vector3.zero && letGo)
{
rb.velocity *= velocityDecreaseRate;
}
if (rb.angularVelocity != Vector3.zero && letGo)
{
rb.angularVelocity *= velocityDecreaseRate;
}
}
}
Answer by sannem · Mar 04, 2021 at 10:11 PM
@Camden9 Hi,
I also found this old script, but whenever I update it to your script, I still get errors:
NullReferenceException: Object reference not set to an instance of an object DragRigidbody.HandleInputBegin (UnityEngine.Vector3 screenPosition) (at Assets/Scripts/DragRigidbody.cs:91) DragRigidbody.OnMouseDown () (at Assets/Scripts/DragRigidbody.cs:72)
NullReferenceException: Object reference not set to an instance of an object DragRigidbody.HandleInputEnd () (at Assets/Scripts/DragRigidbody.cs:121) DragRigidbody.OnMouseUp () (at Assets/Scripts/DragRigidbody.cs:84)
it seems the jointTrans variable is always null, how did you fix that?
Your answer
Follow this Question
Related Questions
Trying to simulate a "Slime" like soft body ball. 0 Answers
How can I use a Spring Joint to pull two objects together? 0 Answers
Car will only turn right (& ignored collders) 0 Answers
Why my gravity direction is rotating with transform.rotation? 1 Answer
Physics.Overlapsphere giving me a null reference exception 1 Answer