Unity3D Getting position of OVRCameraRig - unity3d

I want to attach an object to the OVRCameraRig and then use its position, which is offset from the rig.
However, my object is always static, irrespective of where the headset is.
This only happens with the OVRCameraRig. If I use a normal MainCamera I get the right data. But I'm not getting other aspects, like floor level, of the OVRCameraRig!
Is there some way to get the actual position of the OVRCameraRig?

Afaik the OVRCameraRig itself doesn't move.
What you probably want to get is the position of the centerEyeAnchor instead
// somehow get the reference e.g. using GetComponent
OVRCameraRig overCameraRig;
var position = overCameraRig.centerEyeAnchor.position;
Regardless of the value of usePerEyeCameras the centerEyeAnchor's position is always updated.

Try the following code to get the OVRCameraRig position using the centerEyeAnchor attribute.
using UnityEngine;
public class OVRCameraPosTest : MonoBehaviour {
[SerializeField] private OVRCameraRig overCameraRig;
void Start() {
Vector3 cameraPos = GetCameraPos();
Debug.Log("Camera Position: " + cameraPos);
}
Vector3 GetCameraPos() {
// Remove this line if you are refering the OVRCameraRig component
// through the inspector to the script.
overCameraRig = GameObject.Find("OVRCameraRig").GetComponent<OVRCameraRig>();
return overCameraRig.centerEyeAnchor.position;
}
}

Related

Unity3D: Raycaster.Raycast on UI, get Worldposition of the hit point

I am in UNity3D. I am trying to raycast on UI Element and get the world position of the hit. I have the small test code here. It gives me the name of the target UI Element, but not the position. The world position of the hit is always (0,0,0). Please, can someone suggest, how i can get it right? thank you a lot.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class RaycasterRayScriptTest : MonoBehaviour
{
[SerializeField] private GraphicRaycaster m_Raycaster;
private PointerEventData m_PointerEventData;
private EventSystem m_EventSystem;
[SerializeField] private Vector3 HitPosition;
// Update is called once per frame
void Update()
{
m_PointerEventData = new PointerEventData(m_EventSystem);
m_PointerEventData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
m_Raycaster.Raycast(m_PointerEventData, results);
foreach (RaycastResult result in results)
{
Debug.Log("Hit " + result.gameObject.name);
HitPosition = result.worldPosition;
Debug.Log("HitPosition " + HitPosition.ToString());
}
}
}
I just solved this problem. You have to set Canvas Render Mode: Screen Space - Camera. Select the camera, that you have to use for the UI. With this UI-Plane will appear as an GameObject in the world. But the ui-plane position is not adjustable, so you have to move the camera back and adjust the field of view of the camera.
And because the UI-Plane is now an Object, the code
HitPosition = result.worldPosition;
works now.
without the changes on the canvas and camera, the code doesn't work, because plane of ui is virtual and it's position set to the camera position. So if you try to get the worldPosition, it uses the distance betwenn camera and UI-Plane, and since it is zero, you will get zero for the worldPosition as well.

Unity RectTransform.GetLocalCorners(Vector3[] fourCornersArray) result not change as object;s position changing

my brothers and sisters from another mother : )
I'm trying using unity to implement a swipe menu, which is like the apps menu on a smart phone. I want to get the current corner's local location value, so I can use them as a reference to do some stuff. However, while I'm dragging the object, the corners' value seems remain fixed, which looks weird to me, since the object's relative position (local position) to its parent is definitely changed, I don't know why the corners' location position can all the way just stay the same.
public class pageSwiper: MonoBehaviour, IDragHandler
{
private Vector3 panelLocation;
void start() {panelLocation = transform.position;}
public void OnDrag(PointerEventData data)
{
float difference = data.pressPosiiton.x - data.position.x;
transform.position = panelLocation - new Vector3(difference,0,0);
Vector3[] corners = new Vector3[4];
GetComponent<RectTransform>().GetLocalCorners(corners);
Debug.Log(corners[0].x)
Debug.log(corners[3].x)
}
}
while I using using pointer (mouse) drag the object, the Debug's log value always be the same. Should they change as the object moving, shouldn't they?
You are using GetLocalCorners which are relative to the center of your object.
You can try using GetWorldCorners.

Why the IK controller is not exist in the ThirdPersonController Animator component in the Inspector?

I'm trying to follow the instructions in the unity documents how to use Inverse Kinematics in this page:
Inverse Kinematics
But i don't have the IK Animator Controller when i select Controller for the Animator.
I tried adding the script now. But the hand the right hand is folded to the other side. It's not like it's holding the flash light: The script is attached to the ThirdPersonController. And i dragged to the script in the Inspector to the rightHandObj the EthanRightHand and to the lookObj i dragged the Flashlight.
But the hand seems to be wrong way.
This is the script i'm using now the IKControl:
using UnityEngine;
using System;
using System.Collections;
[RequireComponent(typeof(Animator))]
public class IKControl : MonoBehaviour
{
protected Animator animator;
public bool ikActive = false;
public Transform rightHandObj = null;
public Transform lookObj = null;
void Start()
{
animator = GetComponent<Animator>();
}
//a callback for calculating IK
void OnAnimatorIK()
{
if (animator)
{
//if the IK is active, set the position and rotation directly to the goal.
if (ikActive)
{
// Set the look target position, if one has been assigned
if (lookObj != null)
{
animator.SetLookAtWeight(1);
animator.SetLookAtPosition(lookObj.position);
}
// Set the right hand target position and rotation, if one has been assigned
if (rightHandObj != null)
{
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation);
}
}
//if the IK is not active, set the position and rotation of the hand and head back to the original position
else
{
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 0);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 0);
animator.SetLookAtWeight(0);
}
}
}
}
Add an empty game object to the flashlight and target that instead of the flashlight object itself. Hit play and then fiddle with the placement of the empty object until it is where you want it. Then just turn the flashlight into a prefab, stop play mode and make sure the flashlight in the scene matches the prefab (you can just use revert to do that if needed).
Now it would be doing exactly what you want every time. You could even have multiple prefabs with the empty object positioned differently to allow characters with larger or smaller hands to hold it convincingly.

How do I make my Unity3d camera rotate around his following object?

I'm making a game but I do not now how to let my camera rotate with the object he's following. (I did the follow part) Can somebody help me please. I'm using C#.
Please, can you describe what you actually want to do? What does "let my camera rotate with the object" mean?
If you want your camera to exactly follow the gameobject's rotation in a first person camera, you could achieve this by putting your camera as the gameobject's child.
You could also do this using the following code:
[SerializeField]
private Transform obj; //reference the gameobject's transform
void Update()
{
transform.rotation = obj.rotation;
}
You should use the transform.RotateAround to move the camera. This should be done inside the update method in your camera.
For example:
var target:transform;
function Update(){
//...
transform.RotateAround (target.position, Vector3.up, speed * Time.deltaTime);
}
For more information on the rotation method, see the docs.
If you want simple 3rd person camera, you can place camera as a child of your target object - the camera will "stick to it.
If you want to do this in code (for some reasons), something like this should work (attach script to GameObject with Camera component):
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target; // Object to fallow. Select in Inspector
public Vector3 offset = new Vector3(0, 0, -10); // Offset to target
private GameObject container; // Container for our camera
void Start()
{
container = new GameObject("Camera Container"); // Create container (empty GameObject) for camera to avoid unnecessary calculations. It will follow the target object
transform.parent = container.transform; // Make this object child of container
}
//Update your camera follow script in LateUpade(), to be sure that 'target' movement is done
void LateUpdate()
{
//Check if target is selected
if (target == null)
return;
container.transform.position = target.position; // Set container position same as target
container.transform.rotation = target.rotation; // Set container rotation same as target
transform.localPosition = offset; // Move camera by offset inside the container
transform.LookAt(target); // Optionaly, force camera look at target object on any offset
}
}

Drag and Drop between 2 gameObjects

I have 2 Spheres in my scene. I want to be able to drag and drop my mouse from one sphere to the other, and have an indicator (a straight line for example) while dragging. After releasing the mouse button, I want to store in the first sphere the other sphere (as GameObject).
I need this in UnityScript, but I can accept C# ideas.
So far I have thought about onMouseDown event on the first Sphere, and then onMouseEnter to the other sphere, I'll store the data in some global variable (which I donno how to do yet) and in case of onMouseExit I'll just put the global variable as null.
Then onMouseUp on the first Sphere I'll store the global variable in the pressed object (the sphere).
Any tips and tricks on how to do it?
Assumptions/Setup
You're working in a 2D worldspace; the logic for dragging the object for this part of the solution would need changing.
Setting parent after click drag, referred to setting the object you didn't click to be the child of the parent you did click on.
The camera should be an orthographic camera; using a perspective camera will cause the dragging to not align with where you think it should be.
In order to make the dragging work, I created a quad that was used as the 'background' to the 2D scene, and put that on a new layer called 'background'. Then setup the layermask field to only use the background layer.
Create and setup a material for the line renderer, (I'm using a Particles/Additive shader for the above example), and for the parameters of the line renderer I'm using Start Width: 0.75, End Width: 0, and make sure Use World Space is ticked.
Explanation
Firstly setup the otherSphere field to be pointing to the other sphere in the scene. OnMouseDown and OnMouseUp toggle the mouseDown bool, that is used to determine if the line renderer should be updated. These are also used to turn on/off the line renderer, and set/remove the parent transform of the two spheres.
To get the position to be dragged to, I'm getting a ray based off of the mouse position on screen, using the method ScreenPointToRay. If you wanted to create add smoothing to this drag functionality, you should enable the if (...) else statement at the bottom, and set the lerpTime to a value (0.25 worked well for me).
Note; when you release the mouse, the parent is immediately set, as such both objects end up getting dragged, but the child will return to it's former position anyway.
[RequireComponent(typeof(LineRenderer))]
public class ConnectedSphere : MonoBehaviour
{
[SerializeField]
private Transform m_otherSphere;
[SerializeField]
private float m_lerpTime;
[SerializeField]
private LayerMask m_layerMask;
private LineRenderer m_lineRenderer;
private bool m_mouseDown;
private Vector3 m_position;
private RaycastHit m_hit;
public void Start()
{
m_lineRenderer = GetComponent<LineRenderer>();
m_lineRenderer.enabled = false;
m_position = transform.position;
}
public void OnMouseDown()
{
//Un-parent objects
transform.parent = null;
m_otherSphere.parent = null;
m_mouseDown = true;
m_lineRenderer.enabled = true;
}
public void OnMouseUp()
{
//Parent other object
m_otherSphere.parent = transform;
m_mouseDown = false;
m_lineRenderer.enabled = false;
}
public void Update()
{
//Update line renderer and target position whilst mouse down
if (m_mouseDown)
{
//Set line renderer
m_lineRenderer.SetPosition(0, transform.position);
m_lineRenderer.SetPosition(1, m_otherSphere.position);
//Get mouse world position
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out m_hit, m_layerMask))
{
m_position.x = m_hit.point.x;
m_position.y = m_hit.point.y;
}
}
//Set position (2D world space)
//if (m_lerpTime == 0f)
transform.position = m_position;
//else
//transform.position = Vector3.Lerp(transform.position, m_position, Time.deltaTime / m_lerpTime);
}
}
Hope this helped someone.