Beginner Unity developer here, though have moderate background experience in C based languages (Arduino, etc). I’ve set up a basic HTC Vive Virtual Reality demo in which the player can use their controllers to select and place objects - I’m placing objects via a Raycast from one of the controllers, Instantiating it if it intersects with a place which is valid at the point of intersection (RaycastHit.point). This creates objects who’s center is on the ground, or surface where it’ll be placed, so it’s sunken into the ground. Is there anyway to make it so that it will shift up to let the object sit on the ground, or rest with it’s back against the wall? Here is my code.
using UnityEngine;
using System.Collections;
public class Pointer : MonoBehaviour {
/*
//Vive button setup
private Valve.VR.EVRButtonId gripButton = Valve.VR.EVRButtonId.k_EButton_Grip;
private Valve.VR.EVRButtonId triggerButton = Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger;
private Valve.VR.EVRButtonId touchpad = Valve.VR.EVRButtonId.k_EButton_SteamVR_Touchpad;
SteamVR_TrackedObject controller;
*/
public GameObject placedObj;
public float rotationSpeed = 1.0f;
public float laserWidth = 0.01F;
public Material LaserEffect;
GameObject manipObj;
GameObject[] existObj;
public bool alreadyInst = false;
LineRenderer myLine;
RaycastHit hitPos;
void Start () {
//controller = GetComponent<SteamVR_TrackedObject> ();
myLine = gameObject.AddComponent<LineRenderer> ();
myLine.SetWidth (laserWidth, laserWidth);
myLine.enabled = false;
myLine.material = LaserEffect;
}
void Update () {
//steamVR Controller setup
//SteamVR_Controller.Device device = SteamVR_Controller.Input((int)controller.index);
Ray pointerRay = new Ray (this.transform.position, this.transform.forward);
bool hit = Physics.Raycast (pointerRay, out hitPos, 100);
if (hit) {
if (hitPos.collider.tag == "environment") {
myLine.enabled = true;
myLine.SetPosition (0, transform.position);
myLine.SetPosition (1, hitPos.point);
} else {
myLine.enabled = false;
}
} else {
myLine.enabled = false;
}
//if there's a object selected, it's not been instantiated, raycast hits something, and what it's hitting is environment
if (placedObj) {
if (alreadyInst == false) {
if (hit) {
if (hitPos.collider.tag == "environment" || hitPos.collider.tag == "object") {
manipObj = (GameObject)Instantiate (placedObj, hitPos.point, Quaternion.identity);
manipObj.tag = "manip";
alreadyInst = true;
}
}
} else if (!hit) {//if it's not hitting anything, destroy it and reinstantiate it when it hits something again
Destroy (manipObj);
alreadyInst = false;
} else {//repositioning
reposition (hitPos);
//rotate keyboard
if (Input.GetKey(KeyCode.Q)) {
manipObj.transform.Rotate (Vector3.up * rotationSpeed, Space.Self);
}
if (Input.GetKey (KeyCode.E)) {
manipObj.transform.Rotate (Vector3.down * rotationSpeed, Space.Self);
}
/*
//rotate vive (TO BE TESTED)
Vector2 touchPos = device.GetAxis();
if (touchPos.x > 0.5 && device.GetPress (touchpad)) {
manipObj.transform.Rotate (Vector3.down * rotationSpeed, Space.Self);
}
if (touchPos.x < -0.5 && device.GetPress (touchpad)) {
manipObj.transform.Rotate (Vector3.up * rotationSpeed, Space.Self);
}
//Place the object! Vive
if (device.GetPressDown (triggerButton)) {
placedObj = null;
alreadyInst = false;
}
*/
//Place the object! Keyboard
if (Input.GetKeyDown (KeyCode.P)) {
manipObj.tag = "object";
placedObj = null;
manipObj = null;
alreadyInst = false;
}
}
}
/*
//delete the objects
if (device.GetPressDown (gripButton)){
deleteObjs ();
}
*/
if (Input.GetKeyDown (KeyCode.D)) {
deleteObjs ();
}
}
void reposition (RaycastHit pos){
manipObj.transform.position = pos.point;
}
void deleteObjs(){
existObj = GameObject.FindGameObjectsWithTag ("object");
for (int i = 0; i < existObj.Length; i++) {
Destroy (existObj *);*
-
}* - }*
}
placedObj is the object to be placed, I’m passing it in via another script.
Note that a lot of code is commented out, I currently don’t have access to a Vive however I can test it just as well with two cubes and the keyboard.
Thank you for the reply! This helped a lot - however from further searching I used [RaycastHit.Normal][1] to find the angle of the surface I hit, therefore the direction I should shift the object in (for now it's rounded to one of the world axes) [1]: http://docs.unity3d.com/ScriptReference/RaycastHit-normal.html
– Pydronia