I'm new to Unity and I am trying to build a solar system exploration app through unity. I have the environment set up, and now all I need is the ability to look around (via tilting and moving the phone itself, which is android) smoothly. I have the ability to look around, but if I do a complete 180, it seems to invert the physical orientation of the phone with the visual movements in game, e.g. if I have turn 180 degrees, if I tilt the phone down it shifts my vision in game to the right, up results in visual shift to the left. Here is the code I have thus far:
#pragma strict
private var quatMult : Quaternion;
private var quatMap : Quaternion;
function Start () {
Input.gyro.enabled = true;
}
function Update () {
#if UNITY_ANDROID
quatMap = Input.gyro.attitude;
#endif
transform.localRotation = Quaternion.Euler(90, 0, 0) * quatMap * Quaternion(0,0,1,0) /*quatMult*/;
}
Any help is greatly appreciated. Thanks.
This should be what you're looking for: https://gist.github.com/chanibal/baf46307c4fee3c699d5. Just drag it to the camera and it should work.
You might want to remove the reset on touch part (Input.touchCount > 0 in Update) and debug information (the OnGui method).
Related
I'm trying to make an app that responds to the Cardboard.SDK.Tilted flag in some Update() method.
When running in Unity Player, by pressing the Esc button, Cardboard.SDK.Tilted is set to true, so here's all good.
But when i Build the app for Android, Cardboard.SDK.Tilted stays false if I tilt the device. Other VR apps with tilt actions work fine on my phone. Is there any other option I have to enable before building for Android to make this work?
I'm using Unity v5.3.3f1 and a Cardboard SDK v0.6, the devices I've tried on are Xperia Z2, Samsung Galaxy S3 and iPhone 6.
EDIT:
So, I've tried putting this code into both Update() and LateUpdate() methods:
if (Cardboard.SDK.Tilted) {
print("tilted, next scene");
NextScene ();
}
When the screen is tilted, new scene should be loaded.
But as I've said, it works only in Unity Player by pressing the Esc button to trigger the tilt, on a real device nothing happens - the Cardboard.SDK.Tilted variable is never set to true.
I've seen on https://recordnotfound.com/cardboard-unity-googlesamples-6780/issues that there was a issue of discontinuation of Tilt in v0.6, is it possible that this is no longer supported? But it's strange that it works in Unity Player but not on a real device.
I can verify that the Cardboard.SDK.Tilted flag does not appear to working as in previous versions of the SDK. The escape button triggers it in the debugger, but the tilt action does not trigger it in builds.
However, you can implement an equivalent quite simply with Input.acceleration:
float angle = 80.0f / 360.0f * 2.0f * Mathf.PI;
bool isTilted = Mathf.Abs(Input.acceleration.normalized.x) > Mathf.Sin(angle);
if (Cardboard.SDK.Tilted || isTilted)
{
//Action here
}
If the device's acceleration is entirely due to gravity, the angle float is the angle of the device from horizontal. Attempting to normalize a Vector3 that is too small sets it to zero, so small vectors shouldn't trip the conditional. Pre-calculate your sine to save a cycle.
I'm working on a Google Cardboard project, right now i have a demo for Android where u can look around in a special scene i build in UNITY 3D, everything is working fine & looking good, but what I really want is:
I want to walk forward when I press the Google Cardboard magnet button.
I found a few script's on the web, but I do not know exactly how to make these scripts work in my UNITY project.
Can anybody help me further with this?
Assuming you are able to read the magnet input correctly. This is how I did an FPS style controller script:
In Unity5 import the asset package Standard Assets/Characters.
Create an instance of RigidBodyFPSController.prefab from that package.
Remove it's child object, "MainCamera"
Import the Google cardboard unitypackage.
Replace the "MainCamera" you removed in step #3 with CardboardMain.prefab
Update or modify a copy of RigidbodyFirstPersonController.cs GetInput() method.
GetInput() with Google Cardboard forward movement fallback:
private Vector2 GetInput()
{
Vector2 input = new Vector2
{
x = Input.GetAxis("Horizontal"),
y = Input.GetAxis("Vertical")
};
// If GetAxis are empty, try alternate input methods.
if (Math.Abs(input.x) + Math.Abs(input.y) < 2 * float.Epsilon)
{
if (IsMoving) //IsMoving is the flag for forward movement. This is the bool that would be toggled by a click of the Google cardboard magnet
{
input = new Vector2(0, 1); // go straight forward by setting positive Vertical
}
}
movementSettings.UpdateDesiredTargetSpeed(input);
return input;
}
Google's SDK only support's detecting a magnet "click". If you want to hold down the magnet to move forward, I recommend using Cardboard Controls+ from the Unity3D Asset Store.
I'm having a hard time to pan a view of a gameObject in Unity3d. I'm new to scripting and I'm trying to develop an AR (Augmented Reality) application for Android.
I need to have a gameObject (e.g. a model of a floor), from the normal top down view, rendered to a "pseudo" iso view, inclined to 45 degrees. As the gameObject is inclined, I need to have a panning function on its view, utilizing four (4) buttons (for left, right, forward(or up), backward(or down)).
The problem is that, I cannot use any of the known panning script snippets around the forum, as the AR camera has to be static in the scene.
Need to mention that, I need the panning function to be active only at the isometric view, (which I already compute with another script), not on top down view. So there must be no problem with the inclination of the axes of the gameObject, right?
Following, are two mockup images of the states, the gameObject (model floor) is rendered and the script code (from Unity reference), that I'm currently using, which is not very much functional for my needs.
Here is the code snippet, for left movement of the gameObject. I use the same with a change in -, +speed values, for the other movements, but I get it only move up, down, not forth, backwards:
#pragma strict
// The target gameObject.
var target: Transform;
// Speed in units per sec.
var speedLeft: float = -10;
private static var isPanLeft = false;
function FixedUpdate()
{
if(isPanLeft == true)
{
// The step size is equal to speed times frame time.
var step = speedLeft * Time.deltaTime;
// Move model position a step closer to the target.
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}
static function doPanLeft()
{
isPanLeft = !isPanLeft;
}
It would be great, if someone be kind enough to take a look at this post, and make a suggestion on how this functionality can be coded the easiest way, as I'm a newbie?
Furthermore, if a sample code or a tutorial can be provided, it will be appreciated, as I can learn from this, a lot. Thank you all in advance for your time and answers.
If i understand correctly you have a camera with some fixed rotation and position and you have a object you want to move up/down/left/right from the cameras perspective
To rotated an object to a set of angles you simply do
transform.rotation = Quaternion.Euler(45, 45, 45);
Then to move it you use the cameras up/right/forward in worldspace like this to move it up and left
transform.position += camera.transform.up;
transform.position -= camera.transform.right;
If you only have one camera in your scene you can access its transform by Camera.main.transform
An example of how to move it when someone presses the left arrow
if(Input.GetKeyDown(KeyCode.LeftArrow))
{
transform.position -= camera.transform.right;
}
I try to create game for Android and I have problem with high speed objects, they don't wanna to collide.
I have Sphere with Sphere Collider and Bouncy material, and RigidBody with this param (Gravity=false, Interpolate=Interpolate, Collision Detection = Continuous Dynamic)
Also I have 3 walls with Box Collider and Bouncy material.
This is my code for Sphere
function IncreaseBallVelocity() {
rigidbody.velocity *= 1.05;
}
function Awake () {
rigidbody.AddForce(4, 4, 0, ForceMode.Impulse);
InvokeRepeating("IncreaseBallVelocity", 2, 2);
}
In project Settings I set: "Min Penetration For Penalty Force"=0.001, "Solver Interation Count"=50
When I play on the start it work fine (it bounces) but when speed go to high, Sphere just passes the wall.
Can anyone help me?
Thanks.
Edited
var hit : RaycastHit;
var mainGameScript : MainGame;
var particles_splash : GameObject;
function Awake () {
rigidbody.AddForce(4, 4, 0, ForceMode.Impulse);
InvokeRepeating("IncreaseBallVelocity", 2, 2);
}
function Update() {
if (rigidbody.SweepTest(transform.forward, hit, 0.5))
Debug.Log(hit.distance + "mts distance to obstacle");
if(transform.position.y < -3) {
mainGameScript.GameOver();
//Application.LoadLevel("Menu");
}
}
function IncreaseBallVelocity() {
rigidbody.velocity *= 1.05;
}
function OnCollisionEnter(collision : Collision) {
Instantiate(particles_splash, transform.position, transform.rotation);
}
EDITED added more info
Fixed Timestep = 0.02 Maximum Allowed Tir = 0.333
There is no difference between running the game in editor player and on Android
No. It looks OK when I set 0.01
My Paddle is Box Collider without Rigidbody, walls are the same
There are all in same layer (when speed is normal it all works) value in PhysicsManager are the default (same like in image) exept "Solver Interation Co..." = 50
No. When I change speed it pass other wall
I am using standard cube but I expand/shrink it to fit my screen and other objects, when I expand wall more then it's OK it bouncing
No. It's simple project simple example from Video http://www.youtube.com/watch?v=edfd1HJmKPY
I don't use gravity
See:
Similar SO Question
A community script that uses ray tracing to help manage fast objects
UnityAnswers post leading to the script in (2)
You could also try changing the fixed time step for physics. The smaller this value, the more times Unity calculates the physics of a scene. But be warned, making this value too small, say <= 0.005, will likely result in an unstable game, especially on a portable device.
The script above is best for bullets or small objects. You can manually force rigid body collisions tests:
public class example : MonoBehaviour {
public RaycastHit hit;
void Update() {
if (rigidbody.SweepTest(transform.forward, out hit, 10))
Debug.Log(hit.distance + "mts distance to obstacle");
}
}
I think the main problem is the manipulation of Rigidbody's velocity. I would try the following to solve the problem.
Redesign your code to ensure that IncreaseBallVelocity and every other manipulation of Rigidbody is called within FixedUpdate. Check that there are no other manipulations to Transform.position.
Try to replace setting velocity directly by using AddForce or similar methods so the physics engine has a higher chance to calculate all dependencies.
If there are more items (main player character, ...) involved related to the physics calculation, ensure that their code runs in FixedUpdate too.
Another point I stumbled upon were meshes that are scaled very much. Having a GameObject with scale <= 0.01 or >= 100 has definitely a negative impact on physics calculation. According to the docs and this Unity forum entry from one of the gurus you should avoid Transform.scale values != 1
Still not happy? OK then the next test is starting with high velocities but no acceleration. At this phase we want to know, if the high velocity itself or the acceleration is to blame for the problem. It would be interesting to know the velocities' values at which the physics engine starts to fail - please post them so that we can compare them.
EDIT: Some more things to investigate
6.7 m/sec does not sound that much so that I guess there is a special reason or a combination of reasons why things go wrong.
Is your Maximum Allowed Timestep high enough? For testing I suggest 5 to 10x Fixed Timestep. Note that this might kill the frame rate but that can be dfixed later.
Is there any difference between running the game in editor player and on Android?
Did you notice any drops in frame rate because of the 0.01 FixedTimestep? This would indicate that the physics engine might be in trouble.
Could it be that there are static colliders (objects having a collider but no Rigidbody) that are moved around or manipulated otherwise? This would cause heavy recalculations within PhysX.
What about the layers: Are all walls on the same layer resp. are the involved layers are configured appropriately in collision detection matrix?
Does the no-bounce effect always happen at the same wall? If so, can you just copy the 1st wall and put it in place of the second one to see if there is something wrong with this specific wall.
If not to much effort, I would try to set up some standard cubes as walls just to be sure that transform.scale is not to blame for it (I made really bad experience with this).
Do you manipulate gravity or TimeManager.timeScale from within a script?
BTW: are you using gravity? (Should be no problem just
I'm trying to detect shaking event using Cordova 2.2.0 for android devices.
I found some question related to this topic but t's in native code for example this question and this question.
Does anyone knows how to detect this event using phonegap Cordova ? or I should write a plugin ?
You can try shake.js. Ive been looking into it, but not implemented it. It looks promising.
Use the accelerometer to store the previous values (x, y and z). Defining the thresholds (x,y,z) you can detect shaking if the different betwen the previosValues and the actual once (event.value[i] where i=x,y ans z) is higher than the thresholds.
You also can use the magnitude of the acceleration values (Acc=sqrt(x*x+y*y+z*z)) or the timestamp to obtain better results.
Cordova offers the device-motion plugin, which (surprisingly) exposes a navigator.accelerometer object, instead of aligning with the W3C deviceorientation/devicemotion standard published since 2011.
When the device lays flat on a surface, the (x, y, z) acceleration will be (0, 0, 9.81). The basic idea for detecting a shake is to watch the acceleration with a given frequency, calculate the delta from the previous sample, and decide if it's larger than a threshold.
navigator.accelerometer.watchAcceleration(onSuccess, onError, { frequency: 300 });
// Assess the current acceleration parameters to determine a shake
function onSuccess(acceleration) {
var accelerationChange = {};
if (previousAcceleration.x !== null) {
accelerationChange.x = Math.abs(previousAcceleration.x - acceleration.x);
accelerationChange.y = Math.abs(previousAcceleration.y - acceleration.y);
accelerationChange.z = Math.abs(previousAcceleration.z - acceleration.z);
}
previousAcceleration = {
x: acceleration.x,
y: acceleration.y,
z: acceleration.z
};
if (accelerationChange.x + accelerationChange.y + accelerationChange.z > sensitivity) {
// Shake detected, invoke callback
}
}
A plugin doing that is Lee Crossley's cordova-plugin-shake-detection.