Get interacted object in htc Vive - c#

I just start to learn HTC vive app development with unity and want to interact with Object and want to get it as controller interact with it.
Try to learning form StreamVR Unity Toolkit documentation. I found a scene in sample demo where Gameobject are interacting through controller but there are so many scripts involved. I am amazed that on a cube VRTK_InteractalbeObject is attached and it is responding to controller. how can i get interacted object in htc vive.?

So, here is one of many solutions to interact with objects with controllers - I will show here the easiest one.
A. Find [CamerRig] prefab from SteamVR folder and place it in hierarchy:
B. Find Controller (right)->Model GameObject in it:
C. Create GameObject with Rigidbody and SphereCollider and place it as child of Controller (right)->Model GameObject
C.1. Be sure that this object is in same position as Model GameObject
D. Now play the game, and moving your right vive controller push some other GameObjects that have Rigidbody and any Collider.
E. To use vive controller Buttons use this script, and place it on Controller (right) GameObject.
public class VIVEController : MonoBehaviour
{
public SteamVR_TrackedObject trackedObj;
private SteamVR_Controller.Device controller;
void Start ()
{
controller = SteamVR_Controller.Input ((int)trackedObj.index);
}
void Update ()
{
if (controller.GetPressDown (Valve.VR.EVRButtonId.k_EButton_SteamVR_Trigger))
{
OnTriggerPressed ();
}
if (controller.GetPressDown (Valve.VR.EVRButtonId.k_EButton_SteamVR_Touchpad))
{
OnTouchpadPressed ();
}
}
private void OnTriggerPressed()
{
Debug.Log("OnTriggerPresse");
}
private void OnTouchpadPressed()
{
Debug.Log("OnTouchpadPressed");
}
}
F. Assign from inspector trackedObj (It is on same GameObject as this script)
G. Find script SteamVR_RenderModel and comment out in method LoadComponents
for (int i = 0; i < t.childCount; i++)
{
var child = t.GetChild(i);
child.gameObject.SetActive(false);
StripMesh(child.gameObject);
}
This is necessary, as otherwise your custom GameObject with collider that is child of controller model, will become inactive.
Resuming - it is very easy, but you need to do quite few steps.
Try playing with controllers buttons, to for instance push object only when you press trigger.
As bonus, here is small game I made with same approach:
https://www.youtube.com/watch?v=kzX7Iw6cHZ8

Related

Unity Transform not updating position realtime

I am trying to create a simple scriptable object for my shoot ability. I have that aspect working, but as I try to set my Transform to my player, it does not update the shoot position. I am very new to C#, and this script isnt complete. I still need to add the functionality to destroy the created objects. Any help would be greatly appreciated. I suspect I need to add an update function but im am not certain how to do this.
using UnityEngine.InputSystem;
using UnityEngine.AI;
using UnityEngine;
namespace EO.ARPGInput
{
[CreateAssetMenu]
public class Shoot : Ability
{
public Transform projectileSpawnPoint;
public GameObject projectilePrefab;
public float bulletSpeed = 10;
public float bulletLife = 3;
public override void Activate(GameObject parent)
{
var projectile = Instantiate(projectilePrefab, projectileSpawnPoint.position, projectileSpawnPoint.rotation);
projectile.GetComponent<Rigidbody>().velocity = projectileSpawnPoint.forward * bulletSpeed;
Destroy(projectile, bulletLife);
void OnCollisionEnter(Collision collision)
{
Destroy(projectile);
}
}
}
}
I'm still new to Unity and coding also, so take my advice with a load of salt :P.
It may be best to have a transform on your character (say just past the barrel of the player's gun) that you can put as the projectileSpawnPoint. In your code the projectileSpawnPoint is never set. Your first line of code in the "Activate" method should be something like:
public override void Activate(GameObject parent)
{
projectileSpawnPoint = playerGunBarrelTransform.transform.position;
var projectile = Instantiate(projectilePrefab, projectileSpawnPoint.position, projectileSpawnPoint.rotation);
projectile.GetComponent<Rigidbody>().velocity = projectileSpawnPoint.forward * bulletSpeed;
Destroy(projectile, bulletLife);
For destroying the projectile afterward you can keep it as you have it in OnCollision. howeer, with bullets in particular, since they tend to be instantiated A LOT and then destroyed afterward it would be best to use an object pooler for them to instantiate several of them on start and then disable and enable them as needed so you can resuse them instead of making new ones every time.
you have to create a new script that derives from Monobehaviour for your projectiles. attach that script to the projectile prefab and place the OnCollisionEnter method in that script. now your projectiles should get destroyed when touching another collider. make sure that there is a rigidbody component attached to the projectile.

Unity 3D Counting Number of Agent Passes through a door

I am trying to make fire evacuation simulation by using Unity. I need to count the number of agent passes through the exit door during the evacuation. Is there any way to do it ?
You could set up a simple trigger collider system.
First, you would place a box collider at the exit door, and set it to trigger so it isn’t a solid object (objects can path through it, rather than walk into it). Now, add a Rigidbody to this box collider, and set first drop-down menu that says ‘Dynamic’ to ‘Kinematic’. Now, a way to count them. We will ad the following script to the box collider object:
using UnityEngine;
public class ExitDoor : MonoBehavour
{
void OnTriggerEnter(Collider obj)
{
if (obj.gameObject.tag == “agent”)
{
}
}
}
This doesn’t work yet, because we don’t have anything other than an OnTriggerEnter statement. OnTriggerEnter is called every time either a game object passes through a trigger collider or this game object passes through a trigger collider. We set up an if statement to detect if the game object that passed through it has a certain tag. We are searching for a tag called “agent”. Set each agent’s tag to “agent”. Now we should start a counting system.
using UnityEngine;
public class ExitDoor : MonoBehavour
{
public int agents;
void OnTriggerEnter(Collider obj)
{
if (obj.gameObject.tag == “agent”)
{
agents += 1;
}
}
}
Now, we add 1 to a variable each time an agent enters the collider. The only problem with this is that if the agent goes through the collider twice, it will count it twice.
This system is done, but now you might want to access this from different scripts. We will use GetComponent<>() to access the script. Add this to your game management script, or whatever you want to be accessing this:
using UnityEngine;
public class GameManagement : MonoBehavour
{
public GameObject ExitDoor;
public int agents;
void Update()
{
agents = ExitDoor.GetComponent<ExitDoor>().agents;
if (agents == 10)
{
Debug.Log(“10 agents have exited.”);
}
}
}
Now, we access the script ExitDoor, and get agents from it. Make sure you set the ExitDoor variable from the game management script to the box collider game object used for counting.
This was untested and if you get any bugs or this wasn’t what you wanted, comment on this post to ask me.

Score Count not working on a prefab

This is semi complicated of a question but I'll do my best to explain it:
I am making this mobile game in which you have to shoot four cubes. I'm trying to make it so when the cubes are shot by a bullet, they're destroyed and a UI text says 1/4, to 4/4 whenever a cube is shot. But it's being really weird and only counts to 1/4 even when all four cubes are shot and destroyed. I put these two scripts on the bullets (I made two separate scripts to see if that would do anything, it didn't)
And to give a better idea of what I'm talking about, here's a screenshot of the game itself.
I've been using Unity for about 6 days, so I apologize for anything I say that's noob-ish.
EDIT
So I combined the two scripts onto an empty gameobject and here's the new script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class GameManagerScript : MonoBehaviour {
public GameObject cubes;
public Text countText;
public int cubeCount;
public Transform target;
// Use this for initialization
void Start () {
}
void OnTriggerEnter(Collider other)
{
cubes = other.gameObject;
}
// Update is called once per frame
void Update () {
cubes.transform.position = Vector3.MoveTowards(transform.position, target.position, 1f * Time.deltaTime);
if (cubes.gameObject.tag == "BULLET")
{
cubeCount = cubeCount + 1;
countText.text = cubeCount + "/4";
cubes.SetActive(false);
}
}
}
ANOTHER EDIT
I tried everything, so is there a way to detect when all the children in a parent on the Hierarchy are destroyed? Instead of counting up? This can give a better idea:
So I want to be able to detect when Cube, Cube1, Cube2, and Cube3 have all been destroyed.
The answer is pretty simple: Since every individual bullet has that script, each bullet has its own score.
For something like a score you want a single spot to store it, e.g. a script on an empty gameobject that serves as game controller. Just access that in the collision and increase the score (maybe have a look on singletons here).
You can combine those two scripts and actually it might be better to not have this on the bullet, but on the target because there are probably less of them which will save you some performance. (And it does more sense from a logical point of view.)
Edit:
I assume you create the bullets using Instantiate with a prefab. A prefab (= blueprint) is not actually in the game (only objects that are in the scene/hierarchy are in the game). Every use of Instantiate will create a new instance of that prefab with it's own version of components. A singleton is a thing that can only exist once, but also and that is why I mention it here, you can access it without something like Find. It is some sort of static. And an empty gameobject is just an object without visuals. You can easily create one in unity (rightclick > create empty). They are typically used as container and scriptholders.
Edit:
What you want is:
An empty gameobject with a script which holds the score.
A script that detects the collision using OnTriggerEnter and this script will either be on the bullets or on the targets.
Now, this is just a very quick example and can be optimized, but I hope this will give you an idea.
The script for the score, to be placed on an empty gameobject:
public class ScoreManager : MonoBehaviour
{
public Text scoreText; // the text object that displays the score, populate e.g. via inspector
private int score;
public void IncrementScore()
{
score++;
scoreText.text = score.ToString();
}
}
The collision script as bullet version:
public class Bullet : MonoBehaviour
{
private ScoreManager scoreManager;
private void Start()
{
scoreManager = GameObject.FindWithTag("GameManager").GetComponent<ScoreManager>(); // give the score manager empty gameobject that tag
}
private void OnTriggerEnter(Collider other)
{
if(other.CompareTag("Target") == true)
{
// update score
scoreManager.IncrementScore();
// handle target, in this example it's just destroyed
Destroy(other.gameObject);
}
}
}

Unity Networking: can't spawn scene objects on all clients

I can't really figure out how to solve my problem. I have been looking for an answer but I couldn't find anything.
I have a button in my scene that can be pressed both by client and host. When the button is pressed, it creates a cube in the scene. The problem is that: the cube can be created only by the host and the host is the only user that can see it and manipulate it.
My code is:
public class CreateCube : NetworkBehaviour {
GameObject cubo;
float lastCollisionTime=0;
float collisionTime=0;
void OnCollisionExit(Collision other) {
collisionTime = Time.time;
if (collisionTime - lastCollisionTime >1.5) {
CmdCreaCubo ();
lastCollisionTime = collisionTime;
}
}
}
}
[Command]
void CmdCreaCubo(){
GameObject cubo=Instantiate(Resources.Load("MyPrefabs\\Oggetti\\CubeGrasp")) as GameObject;
cubo.transform.position = new Vector3 (-5.88f, 7.51f, -19f);
cubo.name = "CubeGrasp";
NetworkServer.Spawn (cubo);
}
}
Could anyone help me please?
Thank you so much
Instead using simple Instantiate you should need to use Network.Instantiate
The given prefab will be instanted on all clients in the game.
Synchronization is automatically set up so there is no extra work
involved.

Unity: avatar creation

I'm making my own avatar builder in Unity and I'm stuck on a few key bits I need to implement.
Right now I have taken the avatar that Unity provide with its Mechanim tutorial and I've gave the hat a tag and have instantiated an object at that location. This point is simply an empty game object attached as a child to the head of the model. However I'm having issues making the newly spawned object move and stay with the head as the animation plays. When the avatar moves, the hat just stays in one static position.
How can I make it so that the hat stays with the players head and moves and rotates as the animation is rotating?
My code is really simple as I've no prior experience trying do what I'm doing so even if someone could point me in the right direction on how to build an avatar creator in Unity, I'd appreciate it.
My code as it stands:
public GameObject equipItem;
public GameObject hat;
// Use this for initialization
void Start ()
{
hat = GameObject.FindGameObjectWithTag("Hat");
}
// Update is called once per frame
void Update () {
}
void OnGUI()
{
if(GUI.Button(new Rect(0,0, 100, 50), "Equip Item"))
{
SpawnWeapon();
}
}
void SpawnWeapon()
{
Instantiate(equipItem, hat.transform.position, hat.transform.rotation);
}
What you are missing is making the new object a child to the object you want it to follow. This can be done in the transform of the new object
void SpawnWeapon()
{
GameObject newObject = Instantiate(equipItem, hat.transform.position, hat.transform.rotation) as GameObject;
newObject.transform.parent = hat.transform;
}
this is the same a dragging the new object onto the other object in the inspectors hierarchy window and thus causing it to inherit all transformations made to the parent

Categories