Skip to content
Snippets Groups Projects
Commit f349d112 authored by David Huss's avatar David Huss :speech_balloon:
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FearfulCube : MonoBehaviour, IGazeable
{
// This needs to implement Act because ^ up there we use the interface
// IGazable. This means we "promise" to the compiler to implement all the
// methods defined in that interface. Note that only the method header
// needs to match, what you do inside the {} is totally up to you.
//
// This basically allows you to implement a lot of different reaction for
// the same Gaze that hits the object.
public void Act(GameObject gazingObject, float distance)
{
// Log who gazed at this object and from where
Debug.LogFormat("I have been gazed at by {0} from a distance of {1} m", gazingObject.name, distance);
// Jump 0.5 m to the right if gazed upon
Vector3 temp = new Vector3(0.5f,0,0);
transform.position += temp;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gazing : MonoBehaviour
{
public bool ShowRays = true;
GameObject lastHit = null;
// See Order of Execution for Event Functions for information on FixedUpdate() and Update() related to physics queries
void FixedUpdate()
{
// Bit shift the index of the layer (8) to get a bit mask
int layerMask = 1 << 8;
// This would cast rays only against colliders in layer 8.
// But instead we want to collide against everything except layer 8. The ~ operator does this, it inverts a bitmask.
layerMask = ~layerMask;
RaycastHit hit;
// Does the ray intersect any objects excluding the player layer
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
{
// Get Component that inherits from IGazeable interface you can easily implement your
// own methods using this interface.
var gazedAt = hit.transform.gameObject.GetComponent<IGazeable>();
// Check if the hit object has any component on it that implements IGazeable
if (gazedAt != null) {
gazedAt.Act(this.gameObject, hit.distance);
}
// If Debugging is active show the ray and print debugging information
if (ShowRays) {
// Paint the ray
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
// Only print a debug message if the last Object was null or not the same as before
// to avoid spamming the console
if (lastHit == null || lastHit != hit.transform.gameObject) {
// Print whether the gazed at object has a IGazeable Component on it or not
if (gazedAt == null){
Debug.LogFormat("Gaze hit {0} (not gazable)", hit.transform.gameObject.name);
}else{
Debug.LogFormat("Gaze hit {0} (gazable)", hit.transform.gameObject.name);
}
// Finally update the lastHitvariable to avoid duplicate log messages
lastHit = hit.transform.gameObject;
}
}
}else{
// if the Ray didn't hit any GameObject reset it to null again
lastHit = null;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IGazeable
{
void Act(GameObject gazingObject, float distance);
}
# Gazing
This allows objects to react to being looked at. The behavior of the gazed upon ("gazeable") object can be customized.
1. Add `Gazing.cs` to your main camera (or to `OVRPlayerController > OVRCameraRig > TrackingSpace > CenterEyeAnchor` if you are using Oculus VR glasses). There are not many options to this script, you can switch on or off the display of rays.
2. Add `IGazable.cs` simply to your assets (no need to add it to the scene)
3. Use `FearfulCube.cs` as an example to build your own behaviors
## Details
The technique behind this is Raycasting. This means the _gazing_ object shoots out "rays" every Physics-Frame (`FixedUpdate()`) and if it hits a collider it checks if the hit object has a component on it, that implements the Interface `IGazable`.
A interface is simply a common set of commands a thing needs to implement. In our case it is defined as follows:
```csharp
// IGazeable.cs
public interface IGazeable
{
void Act(GameObject gazingObject, float distance);
}
```
Using this we could implement various own functions that all need to use the same function name and definition but can differ in behaviour. E.g. The FearfulCube moves away into x direction:
```csharp
// FearfulCube.cs
public class FearfulCube : MonoBehaviour, IGazeable
{
public void Act(GameObject gazingObject, float distance)
{
// Log who gazed at this object and from where
Debug.LogFormat("I have been gazed at by {0} from a distance of {1} m", gazingObject.name, distance);
// Jump 0.5 m to the right if gazed upon
Vector3 temp = new Vector3(0.5f,0,0);
transform.position += temp;
}
}
```
Another Cube could react differently to be gazed at:
```csharp
// ShyCube.cs
public class ShyCube : MonoBehaviour, IGazeable
{
public void Act(GameObject gazingObject, float distance)
{
Debug.LogFormat("Blush! {0}, leave me alone", gazingObject.name);
}
}
```
The common element here is the `, IGazable` in the class definition on top. This is our promise that we will implement all of the methods mentioned in the `IGazable` Interface definition above (which in this case is just `Act(GameObject gazingObject, float distance)`).
The cool thing about this is, that in `Gazing.cs` we now just have to do this:
```csharp
// Get Component that inherits from IGazeable interface you can easily implement your
// own methods using this interface.
var gazedAt = hit.transform.gameObject.GetComponent<IGazeable>();
// Check if the hit object has any component on it that implements IGazeable
if (gazedAt != null) {
gazedAt.Act(this.gameObject, hit.distance);
}
```
and every gazed at object will use its own customizable `Act()`-function if it has one. If it has none, it just does nothing.
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment