Google Cardboard - How to detect focus on an object? - unity3d

I try to create a VR scene in unity using google cardboard sdk. I add a cube and CardboardMain.prefab to scene. There is an example scene that detect focus on cube. Its hierarchy view is :
I don't know how to add GUIReticle object or prefab like as the image.
How can I detect focus on an object?

Actually you could make the script by your own and it is quite simple.
You could detect whether the user is looking at your object or not by using RayCast from the Main Camera. If the RayCast hit your object, then it is being focused on.
For example:
using UnityEngine;
using System;
[RequireComponent(typeof(Collider))]
public class LookableObject : MonoBehaviour {
[SerializeField]
Transform cam; // This is the main camera.
// You can alternately use Camera.main if you've tagged it as MainCamera
bool focus; // True if focused
Collider gazeArea; // Your object's collider
public void Start () {
gazeArea = GetComponent<Collider> ();
}
public void Update () {
RaycastHit hit;
if (Physics.Raycast (cam.position, cam.forward, out hit, 1000f)) {
focus = (hit.collider == gazeArea);
} else {
focus = false;
}
}
}
Edit: This is just an example. You probably would want to make a script to do the Raycast only just once instead of doing the Raycast on each of your object over and over again to make your project runs faster.

Related

how to fix my enemy turning invisible in play mode UNITY

So, here's my error! im designing a FPS game in unity and im scripting an AI enemy (for now it just moves around randomly) im also using NeoFPS that should be all the background info out of the way as for whats happening:
i can see the enemy in scene view and i can see it in the game view before i press play, when i do press play the enemy disappears in game view but i can still see it trying to move around the little box i put it in and stuff of the sorts via navmesh etc. the collider for the enemy is still there when i go into the box however i cant see it and i shoot through it and do no damage to it whatsoever i will include screenshots and my AI code below (the white capsule is the enemy w AI script inside a little box, the camera is the FPS player
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class AICharacterController : MonoBehaviour
{
private NavMeshAgent m_Agent;
private void Awake()
{
m_Agent = GetComponent<NavMeshAgent>();
}
Vector3 movePosition;
void Update()
{
if (movePosition == Vector3.zero
|| Vector3.Distance(transform.position, m_Agent.destination) < 1)
{
SelectNewDestination();
}
}
void SelectNewDestination()
{
Vector2 pos = Random.insideUnitCircle * 50;
movePosition.x = pos.x;
movePosition.y = pos.y;
NavMeshHit hit = default;
if (NavMesh.SamplePosition(movePosition, out hit, 4, NavMesh.AllAreas))
{
m_Agent.SetDestination(hit.position);
}
}
public void Die()
{
Destroy(gameObject, 0.25f);
}
}
(if you dont see an image below then stackoverflow replaced it with a link and its not working)
If things are invisible in a camera, but not in the scene view then that means that the "Culling Mask" property on the camera is set to ignore the layers the object is on. NeoFPS uses a spawning system, so its quite possible that the camera in the character that's spawned has a different culling mask setup to the camera in the scene that you're looking through outside of play mode. To fix that you would have to find the camera in the character prefab's hierarchy (usually called PlayerCameraSpring) and add your AI's layer to its culling mask.

How do you switch scenes in Unity 2D on collison

I was wondering how I can switch scenes in my 2D Unity game. I put the scenes in the build and the objects are entering in colison. I used this code but it didn't worked:
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneSwitch : MonoBehaviour
{
[SerializeField] private string WhatScene;
void OnTriggerEnter(Collider2D other)
{
if (other.CompareTag("Player"))
{
SceneManager.LoadScene(WhatScene);
}
}
}
Can you help me?
https://i.stack.imgur.com/rpg3t.png
https://i.stack.imgur.com/HoOfl.png
https://i.stack.imgur.com/9GEgi.png
Note that there is
OnTriggerEnter2D(Collider2D) which as parameter takes a Collider2D, not Collider. This one is for 2D physics using Rigidbody2D and Collider2D components.
OnTriggerEnter(Collider) which takes a Collider, **not Collider2D. This one is for 3D physics using Rigidbody and Collider components.
Since you are talking about 2D your method should look like
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
SceneManager.LoadScene(WhatScene);
}
}
If you are using OnTriggerEnter method in unity2D there is a problem, you need to set collision as a trigger and use "OnTriggerEnter2D" method.
In build settings you have to add scenes, there will be a different index attributed to every scenes.
private void OnTriggerEnter2D(Collider other)
{
if (other.CompareTag("TAG"))
{
SceneManager.LoadScene([INDEX OF THE SCENE YOU WANT TO USE]);
}
}
If you want to detect a collision use OnCollisionEnter2D.

Unity2D: play instantiated prefab's animation when prefab is being dragged

I have a prefab that is instantiated when the user buys the item from my In-game store, how ever many is instantiated, the all of prefab has a start position of a certain position. The prefab can be dragged around the scene using this TouchScript package I found online! My issue: I want to play the prefab's animation every time the user is dragging the prefab around the screen, I attempted this by creating a RaycastHit2D function that would allow me to detect if the user has clicked on the prefab's collider, script below:
if (Input.GetMouseButtonDown (0)) {
Vector2 worldPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast (worldPoint, Vector2.zero);
if (hit.collider != null) {
if (this.gameObject.name == "Item5 (1)(Clone)" +item5Increase.i) {
monkeyAnim.SetBool ("draging", true);
Debug.Log (hit.collider.name);
}
} else {
monkeyAnim.SetBool ("draging", false);
}
}
However if I were to buy more than one prefab, all instantiated prefabs will play it's animation when I start to drag only one of the instantiated prefabs, hope I'm making sense. Can some one help me? Thank you!
I faced a similar issue with platforms in my 2D game. The solution I would suggest is to create a GameObject that acts as the current item you wish to animate, and a LayerMask that acts as a filter for which objects your raycast can hit. You can use this LayerMask in conjunction with the Physics2D.Raycast API, which has an overload method that takes a LayerMask as a parameter.
Start by creating a new layer, which can be done by going to the top right of an object in your scene and accessing the "Layer" box. Once you've created a new layer (I called mine "item"), make sure your prefab's layer is assigned correctly.
Then, create an empty object in your scene, and attach this script to it. On that object you will see a dropdown menu that asks which layers your raycast should hit. Assign it the "item" layer; this ensures that your raycast can only hit objects in that layer, so clicking on anything else in your game will produce no effect.
using UnityEngine;
public class ItemAnimation : MonoBehaviour
{
private GameObject itemToAnimate;
private Animator itemAnim;
[SerializeField]
private LayerMask itemMask;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
CheckItemAnimations();
}
else if (Input.GetMouseButtonUp(0) && itemToAnimate != null) //reset the GameObject once the user is no longer holding down the mouse
{
itemAnim.SetBool("draging", false);
itemToAnimate = null;
}
}
private void CheckItemAnimations()
{
Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero, 1, itemMask);
if (hit) //if the raycast hit an object in the "item" layer
{
itemToAnimate = hit.collider.gameObject;
itemAnim = itemToAnimate.GetComponent<Animator>();
itemAnim.SetBool("draging", true);
Debug.Log(itemToAnimate.name);
}
else //the raycast didn't make contact with an item
{
return;
}
}
}

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 to handle click on object?

I've tried some examples of code to handle click on object, but they are don't work.
I have object's mesh on scene:
On Main Camera there is one C# Script Component with code:
using UnityEngine;
using System.Collections;
public class cameraAnim3 : MonoBehaviour
{
void Update() {
if (Input.GetMouseButtonDown (0)) { // if left button pressed...
print ("cli!!!");
// create a ray passing through the mouse pointer:
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast (ray, out hit)) { // if something hit...
print ("clicked on object!!!");
// if you must do something with the previously
// selected item, do it here,
// then select the new one:
Transform selected = hit.transform;
selected.gameObject.SetActive (true);
print (selected.gameObject.name);
// do whatever you want with the newly selected
// object
}
}
}
}
When I clicked with left button on the mesh of head, in console message "cli!!!" showed, but no message "clicked on object!!!" was showed.
How to catch click on this mesh?
Answer is here Unity: Object is not being detected by raycast for highlighting
The modern to detect collisions is to implement IPointerClickHandler interface, and ensure that you have an EventSystem and a relevant Raycaster (2d or 3d, depending on what collider are you using) present in the scene. It's much better than writing your own code to manage clicks and pointer positions. Also, the game object itself has to have a Collider component. It can either be a mesh collider, or a more generic (and better for performance) box collider.