- Home /
Question by
LLIV · Jan 26, 2016 at 12:26 PM ·
rotationsnappingspringjointrotation detection
Increment snapping and rotation
Hi I'm trying to write a script that will allow me to snap a circle to increments in it's rotation. However the player needs to drag the circle along it's rotation in the Z - axis not move it with buttons or anything. Dragging Script:
const float k_Spring = 50.0f;
const float k_Damper = 5.0f;
const float k_Drag = 10.0f;
const float k_AngularDrag = 5.0f;
const float k_Distance = 0.2f;
const bool k_AttachToCenterOfMass = false;
private SpringJoint m_SpringJoint;
private void Update()
{
// Make sure the user pressed the mouse down
if (!Input.GetMouseButtonDown(0))
{
return;
}
var mainCamera = FindCamera();
// We need to actually hit an object
RaycastHit hit = new RaycastHit();
if (
!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition).origin,
mainCamera.ScreenPointToRay(Input.mousePosition).direction, out hit, 100,
Physics.DefaultRaycastLayers))
{
return;
}
// We need to hit a rigidbody that is not kinematic
if (!hit.rigidbody || hit.rigidbody.isKinematic)
{
return;
}
if (!m_SpringJoint)
{
var go = new GameObject("Rigidbody dragger");
Rigidbody body = go.AddComponent<Rigidbody>();
m_SpringJoint = go.AddComponent<SpringJoint>();
body.isKinematic = true;
}
m_SpringJoint.transform.position = hit.point;
m_SpringJoint.anchor = Vector3.zero;
m_SpringJoint.spring = k_Spring;
m_SpringJoint.damper = k_Damper;
m_SpringJoint.maxDistance = k_Distance;
m_SpringJoint.connectedBody = hit.rigidbody;
StartCoroutine("DragObject", hit.distance);
}
private IEnumerator DragObject(float distance)
{
var oldDrag = m_SpringJoint.connectedBody.drag;
var oldAngularDrag = m_SpringJoint.connectedBody.angularDrag;
m_SpringJoint.connectedBody.drag = k_Drag;
m_SpringJoint.connectedBody.angularDrag = k_AngularDrag;
var mainCamera = FindCamera();
while (Input.GetMouseButton(0))
{
var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
m_SpringJoint.transform.position = ray.GetPoint(distance);
yield return null;
}
if (m_SpringJoint.connectedBody)
{
m_SpringJoint.connectedBody.drag = oldDrag;
m_SpringJoint.connectedBody.angularDrag = oldAngularDrag;
m_SpringJoint.connectedBody = null;
}
}
private Camera FindCamera()
{
if (GetComponent<Camera>())
{
return GetComponent<Camera>();
}
return Camera.main;
}
}
So what I need is something that can A. Detect which increment the circle is closest too and B. Snap the circle to that increment. I tried using springs because they had a really nice effect but I couldn't figure out how to change where they snapped to. My current method for detecting a moving the circle with rigid bodies and things:
using UnityEngine;
using System.Collections;
public class Rings : MonoBehaviour {
public float MinVelocity = .1f;
public Collider[] ringColliders;
//Don't worry about this it's unrelated.
void Start () {
for (int i=0;i<ringColliders.Length - 1;i++){
Physics.IgnoreCollision(ringColliders[i], ringColliders[i+1]);
}
}
//Evaluates things...
void EvaluateRings (Transform Ring,int i,Rigidbody RB) {
Quaternion rotation = Quaternion.Euler(new Vector3(0f,0f,67.51968f));
if (Ring.rotation.z < 67.51968f){
if (Ring.rotation.z < 3f){
print ("Pass");
Ring.rotation = Quaternion.Euler(new Vector3(Ring.rotation.x,Ring.rotation.y,36f));
// Vector3 Zero_V = new Vector3(0f,0f,0f);
Rigidbody Zer0 = RB;
Zer0.angularVelocity.Set (0f,0f,0f);
RB.angularVelocity = Zer0.angularVelocity;
ringColliders[i].transform.rotation = Ring.rotation;
}
}
}
//Waits for a ring to stop turning...
void FixedUpdate () {
for (int i = 0; i<ringColliders.Length; i++){
Rigidbody RB = ringColliders[i].attachedRigidbody;
if (RB.angularVelocity.z < MinVelocity && RB.angularVelocity.z > 0f) {
EvaluateRings(ringColliders[i].transform,i,RB);
print ("True");
}
}
}
}
And no, I'm not proud of the rings script. I was just trying things to get it working.
Comment