AngularVelocity relative to a CameraRig (VR) - unity3d

Im in a bit of a pickle. I am working on trying to make objects that I release from my hand in VR adopt the correct velocity and angularVelocity of the controller so their release movement feels natural. This is a simple matter of tracking the controller angularvelocity and velocity and passing it to the opbject upon release:
rigid.velocity = controller.currentVelocity;
rigid.angularVelocity = controller.currentAngularVelocity;
However, and here comes the kicker, I also have a locomotion system that happens to rotate the CameraRig with regards to the head of the player and after doing so these values are all wrong and shifted with regards to the cameraRig as so:
cameraRig.transform.RotateAround(headsetCamera.transform.position, Vector3.up, -(headsetCamera.transform.eulerAngles.y - lastHeadRot.y));
lastHeadRot = headsetCamera.transform.eulerAngles;
I have tried looking for some answers like this (ref) and this (ref) but none of it has worked. Any suggestions would be most welcome. When using other forms of locomotion the angularvelocity and velocity get set correctly to the objects thrown but not once I have used the rotateAround on the cameraRig.

I solved this finally, so I thought I would add the solution here.
Instead of using this code to throw objects:
_rigid.velocity = controller.currentVelocity;
_rigid.angularVelocity = controller.currentAngularVelocity;
I used:
_rigid.AddForce(controller.currentVelocity);
_rigid.angularVelocity = controller.currentAngularVelocity;
this solved the issue and the objects now fly in the expected direction no matter what the roation of the parent is.

Related

Stuck Implementing A Way To Rotate A Rigidbody Towards A Point With Rigidbody.AddTorque

So I am kinda stuck on what to do now because as I said I am trying to use Rigidbody.AddTorque to rotate a rigid body towards a certain point, which I was going to use to align a player with a gravitational pull so they can be upright. I have got the input part of the code, I just don't have a way to rotate the player to align with it, without violating the laws of physics with Quaternion.FromToRotation and messing with my character controller too, which I am trying to make entirely physics based rotation wise too to avoid any other problems.
I have experimented with a couple of methods, first I tried adapting my character controller code which used Rigidbody.AddForce to move the player and also dampening unwanted movements, as Rigidbody.AddTorque is basically Rigidbody.AddForce but for rotations, however, it was too weak and just flopping around when I tried it, here's the code for the character controller for calculating the force needed for one axes:
if(projected_speed.x*speed == relative_v.x)
{
applied_speed.x = 0f;
}
else if(Mathf.Sign(projected_speed.x)== -1)
{
applied_speed.x = relative_v.x - Mathf.Abs(projected_speed.x*speed);
}
else if (Mathf.Sign(projected_speed.x) == 1)
{
applied_speed.x = projected_speed.x*speed - relative_v.x;
}
Where projected_speed is the speed the controller wants to be at,relative_v is the relative velocity, and applied_speed is the speed that will be actually applied in Rigidbody.AddForce.
Anyways so maybe I didn't use enough force, as the player is under a gravitational pull, but that would have probably made it flip out or something, anyways so the second thing I tried was a PID controller, and I managed to find a page which explains it pretty well, sadly don't have the link anymore, but when I tried this because you have to tune it, I was stuck doing it, and it just wasn't able to do anything and was just rolling around the floor and sometimes spinning, probably as it couldn't cope with gravity, so that didn't work, so does anyone know how I could finally do this and make my character able to right themselves according to gravity?
Sorry for not indicating that my issue is solved, click here for the answer, credit to Ruzihm.

How to change the orientation of the model itself?

I downloaded a bullet model from TurboSquid.
But the bullet is pointing to the left (negtive X axis).
So the whole thing needed to be turned 90 degree on Y axis to face "forward" (Z axis).
I'm making a first-person shooting game so I needed the bullet to face exactly where the camera was facing.
So if I simply set
bullet.gameObject.transform.rotation = Camera.main.transform.rotation;
The bullet will just facing "left"!
I tried to do a additional rotation after the rotation assignment as follow:
bullet.gameObject.transform.Rotate(Camera.main.transform.up,90);
It worked fine if the view is parallel to the horizon.
But it will started to facing some weird ways if you're shooting up or down!
I also tried to create an empty parent GameObject and throw the bullet in as its child, and set the parent's rotation.
Now it "always" facing "forward" (Z axis)! No matter where I turned my camera!
Could somebody please be so kind and teach me how to fix this!?
Much appreciated!
Wrap your model in a parent object, like this:
Then you can rotate the BulletModel 90 degrees and attach the script that moves the object to the ParentBullet. This should do the trick.
It's usually considered good practice overall to separate your model and logic/actual object like this.
I fixed it by some weird ways!
I just set its forward to the camera's right, and its right to the camera's back.
bullet.gameObject.transform.forward = Camera.main.transform.right;
bullet.gameObject.transform.right = -Camera.main.transform.forward;
But I still don't know why the empty parent GameObject trick don't work!?

Rigidbody Velocity Messing Up Physics UNITY

I am trying to move my player by using rigidbody.velocity:
rigidbod.velocity = new Vector2 (Input.GetAxis ("Horizontal") * maxSpeed, rigidbod.velocity.y);
the problem is, this messes up of my explosion code. The character is supposed to be knocked back when near an explosion. I know why it happens; if the player is still, the rigidbody's X velocity would be returned as 0, meaning any outside forces pushing the player along the X axis would counteract this. So when I add the explosion, the player cuts to his new position a few units away. It looks very unnatural and jerky, as he should be pushed back, but his code is telling him to be still unless a key is pressed. I'm posting this to see if there's any way I can re-write this code to be able to move the player while being pushed correctly from outside forces. I heard that AddForce works, but when I used it, my player's velocity constantly increased. He is wither way too fast or way too slow. Any ideas on how I can get this to work? I tried adding rigidbody.velocity.x after where it says 'maxspeed' hoping that it would allow outside force input, and it works, but it messes up the movement code, making him go way too fast. I can't seem to get both the explosions and the movement code to work correctly at the same time. Any help would be greatly appreciated. Thanks.
which is exactly why in the Unity docs they explicitly state:
In most cases you should not modify the velocity directly, as this can
result in unrealistic behaviour.
instead of modifying the velocity directly, you should be using an AddForce(..)
Vector2 force = new Vector2 (Input.GetAxis ("Horizontal") * maxSpeed, 0f);
rigidbody.AddForce(force);
//or if in update:
rigidbody.AddForce(force * Time.deltaTime);

Modifying Rotation w/ GamePad

I'd like to modify the rotation of the camera object via a gamepad. I have code that works in the editor, but doesn't work on iOS. (However, it looks like it's working but being pushed back on the 2nd frame by the VROne code).
I was able to get this working w/ the Rift, but haven't been able to figure it out with VROne yet. For the Rift I added an "offset" to the rotation that was changed by the GamePad joystick. The offset was calculated into the final rotation that also includes the players look direction.
Any idea what part of the code I'd modify to get this properly working with the VROne sdk?
If you want to use your own GameRotation angles (from the gamepad), the values might be getting overwritten by the integrated HeadTracking. Have you tried disabling the VR Head Tracking Script, in the VROneSDKHead object?
The HeadTracking angles are dealt with in the HeadTrackingIOS class, which calls the native static library. You can try adding your gamepad offset to the Quaternion returned on line 43.
Hope this helps, let us know if it worked!
EDIT: Nevermind, the below code works in the editor, but on the iOS device the camera is still forced ahead. I'll try the other answer.
Cool -- that may work, the above answer. It sounds like what I was looking for.
However, per a suggestion on the Unity forum, I implemented this solution: First I made the VROne Object a child of another empty game object, with the localPosition 0,0,0.
On rotation, I rotate the parent, but first make sure the parent is the same position of the child and then the child localPosition is 0,0,0 - -right now the child is doing the physical movement, and the parent does the rotation. I'm not sure if moving the character controller to the parent would work or make something else funky in the SDK, but this seems to work for now.
if (RightStickX.Value != 0)
{
transform.position = childObject.transform.position;
childObject.transform.localPosition = Vector3(0,0,0);
transform.eulerAngles.y += RightStickX.Value * rotationSpeed * Time.deltaTime;
}
Just in case this would help someone, I was able to solve it in a much simpler way.
The VrOneSDK object is a child of the object that I am rotating with my gamepad.
and then in 'vrHeadTracking.cs' I simply changed
transform.rotation = Quaternion.Inverse(initialRotation) * rot;
to
transform.localRotation = Quaternion.Inverse(initialRotation) * rot;
that way the head tracking is relative to my parent object's rotation.

Unity3d Transform issues when trying to re-parent a Gameobject with sub-Gameobjects

I am trying to grab a Gameobject that's placed in the correct spot and re-parent it to different Gameobject transforms using code. I manage to do this by using ..transform.parent = parent.transform but the rotation and position get messed up. How can I keep it's rotation and position when re-parenting?
Thanks!
Always use gameObject.transform.SetParent(anotherGameObject), or you risk exactly the sort of phenomena you've described. See SetParent docs; there is a second parameter to consider.
The form mentioned in the question still works in many cases, but has been deprecated for a while.
Place all game object that you want to parent, to empty game object(example:"EMPTY\PARENT\EMPTY\CHILD") with scale 1:1:1(in editor)or re-scale your parent game object to 1:1:1