Every 5 seconds I need to take a photo and display it in the world. That part is working fine.
Once a photo is taken it need to disappear 1 second after. That's where I'm stuck.
I've gotten it to disappear but then I cant get the new picture to reappear when its function is called again.
Any ideas?
I've tried:
m_CanvasRenderer.enabled = false;
m_CanvasRenderer.enabled = true;
m_Canvas = null;
m_Canvas.setActive(false);
m_Canvas.setActive(true);
With no luck
public class PhotoCaptureExample : MonoBehaviour
{
GestureRecognizer m_GestureRecognizer;
GameObject m_Canvas = null;
Renderer m_CanvasRenderer = null;
PhotoCapture m_PhotoCaptureObj;
CameraParameters m_CameraParameters;
bool m_CapturingPhoto = false;
Texture2D m_Texture = null;
void Start()
{
Initialize();
InvokeRepeating("TakePhoto", 5.0f, 5.0f);
//StartCoroutine(TakePhoto());
}
void TakePhoto()
{
if (m_CapturingPhoto)
{
return;
}
m_CapturingPhoto = true;
m_PhotoCaptureObj.TakePhotoAsync(OnPhotoCaptured);
}
void OnPhotoCaptured(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
// m_CanvasRenderer.enabled = true;
if (m_Canvas == null)
{
m_Canvas = GameObject.CreatePrimitive(PrimitiveType.Quad);
m_Canvas.name = "PhotoCaptureCanvas";
m_CanvasRenderer = m_Canvas.GetComponent<Renderer>() as Renderer;
m_CanvasRenderer.material = new Material(Shader.Find("AR/HolographicImageBlend"));
}
Matrix4x4 cameraToWorldMatrix;
photoCaptureFrame.TryGetCameraToWorldMatrix(out cameraToWorldMatrix);
Matrix4x4 worldToCameraMatrix = cameraToWorldMatrix.inverse;
Matrix4x4 projectionMatrix;
photoCaptureFrame.TryGetProjectionMatrix(out projectionMatrix);
photoCaptureFrame.UploadImageDataToTexture(m_Texture);
m_Texture.wrapMode = TextureWrapMode.Clamp;
m_CanvasRenderer.sharedMaterial.SetTexture("_MainTex", m_Texture);
m_CanvasRenderer.sharedMaterial.SetMatrix("_WorldToCameraMatrix", worldToCameraMatrix);
m_CanvasRenderer.sharedMaterial.SetMatrix("_CameraProjectionMatrix", projectionMatrix);
m_CanvasRenderer.sharedMaterial.SetFloat("_VignetteScale", 1.0f);
// Position the canvas object slightly in front
// of the real world web camera.
Vector3 position = cameraToWorldMatrix.GetColumn(3) - cameraToWorldMatrix.GetColumn(2);
// Rotate the canvas object so that it faces the user.
Quaternion rotation = Quaternion.LookRotation(-cameraToWorldMatrix.GetColumn(2), cameraToWorldMatrix.GetColumn(1));
m_Canvas.transform.position = position;
m_Canvas.transform.rotation = rotation;
m_CapturingPhoto = false;
float counter = 0; float target = 1;
while (counter < target)
{
counter += Time.deltaTime;
}
// m_CanvasRenderer.enabled = false;
}
}
Related
Im using a Grab Object script that grabs a object that is inside the trigger collider.
But when i try to grab a object with more than 1 object inside the collider it grabs all the objects at the same time (example image with two bricks grabbed at the same time).
I need a rule to grab only the nearest object.
two brick grabbed
im using this script to grab the objects.
Found it on a YT tutorial and tweaked it
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickUp : MonoBehaviour {
public float throwForce = 100;
public bool canHold = true;
public GameObject item;
public GameObject tempParent;
public GameObject poof;
public GameObject vanish;
public GameObject poofParent;
public Transform guide;
public bool isHolding = false;
float distance;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
distance = Vector3.Distance(item.transform.position, guide.transform.position);
if (Input.GetKeyDown("space"))
if (distance <= 6f)
{
isHolding = true;
item.transform.position = tempParent.transform.position;
//Poof
GameObject myPoof = Instantiate(poof, Vector3.zero, Quaternion.identity) as GameObject;
myPoof.transform.parent = poofParent.transform;
myPoof.transform.position = poofParent.transform.position;
Destroy (myPoof, 2);
//Particles
GameObject myVanish = Instantiate(vanish, Vector3.zero, Quaternion.identity) as GameObject;
myVanish.transform.parent = tempParent.transform;
myVanish.transform.position = tempParent.transform.position;
Destroy (myVanish, 4);
}
if (isHolding==true)
{
item.GetComponent<Rigidbody>().useGravity = false;
item.GetComponent<Rigidbody>().detectCollisions = true;
item.GetComponent<Rigidbody>().isKinematic = false;
item.transform.parent = tempParent.transform;
item.transform.position = tempParent.transform.position;
if (Input.GetKeyUp("space"))
{
Debug.Log("Trying to throw");
item.GetComponent<Rigidbody>().AddForce(guide.transform.forward * throwForce);
isHolding = false;
}
}
else
{
item.GetComponent<Rigidbody>().useGravity = true;
item.GetComponent<Rigidbody>().isKinematic = false;
item.transform.parent = null;
}
}
}
There is a sphere cast implemented in Unity's physics system, however it exists for a different purpose. Instead you're looking for Physics.OverlapSphere
Assuming that your guide object should be the center of the sphere you can determine the closest object (closestSelectedObject) in a specified selection radius.
float radiusOfSphere;
float smallesDistance;
Transform closestSelectedObject;
/***/
void Update(){
if(Input.GetKeyDown("space")){
Collider[] hitColliders = Physics.OverlapSphere(guide.transform.position, radiusOfSphere);
if(hitColliders.length > 0){
smallesDistance = radiusOfSphere;
foreach(Collider obj in hitColliders){
float tempDistance = Vector3.Distance(obj.transform.position, guide.transform.position);
if(tempDistance <= smallesDistance){
smallesDistance = tempDistance;
closestSelectedObject = obj;
}
}
/*other stuff that your code does*/
}
}
}
my final functional (Update) code here
Cant make it without your help #derHugo, thank you!
void Update () {
Collider[] hitColliders = Physics.OverlapSphere(guide.transform.position, radiusOfSphere);
var closestSelectedObject = hitColliders.OrderBy(obj => (obj.transform.position - guide.transform.position). sqrMagnitude).FirstOrDefault();
GameObject grabbed = GameObject.Find("grabbedObject");
if (grabbed != null)
{
Debug.Log("existe");
if (Input.GetKeyDown(KeyCode.Space) && !spaceDisabled) {
spaceDisabled = true;
}
}
else
{
if (Input.GetKeyDown("space"))
{
// targetObject does not exist in the scene
Debug.Log("NAOexiste");
if (closestSelectedObject.tag.Contains("CanPickup"))
{
closestSelectedObject.transform.position = tempParent.transform.position;
closestSelectedObject.transform.parent = tempParent.transform;
closestSelectedObject.GetComponent<Rigidbody>().detectCollisions = false;
closestSelectedObject.GetComponent<Rigidbody>().isKinematic = true;
closestSelectedObject.GetComponent<Rigidbody>().useGravity = true;
originalName = closestSelectedObject.name;
closestSelectedObject.name = "grabbedObject";
//Poof
GameObject myPoof = Instantiate(poof, Vector3.zero, Quaternion.identity) as GameObject;
myPoof.transform.parent = poofParent.transform;
myPoof.transform.position = poofParent.transform.position;
Destroy (myPoof, 2);
//Particles
GameObject myVanish = Instantiate(vanish, Vector3.zero, Quaternion.identity) as GameObject;
myVanish.transform.parent = tempParent.transform;
myVanish.transform.position = tempParent.transform.position;
Destroy (myVanish, 4);
}
}
}
if (Input.GetKeyDown(KeyCode.Q))
{
Debug.Log("Q key was pressed.");
grabbed.transform.parent = null;
grabbed.GetComponent<Rigidbody>().detectCollisions = true;
grabbed.GetComponent<Rigidbody>().isKinematic = false;
grabbed.GetComponent<Rigidbody>().useGravity = true;
grabbed.GetComponent<Rigidbody>().AddForce(guide.transform.forward * throwForce);
Input.ResetInputAxes();
grabbed.name = originalName;
}
}
I'm writing a unity editor script which draws a preview scene in the inspector GUI. Basically, I instantiate a prefab with a camera component and move it into a temporary scene. Then I try to draw the scene onto a texture using that camera. My current approach doesn't seem to be working, or maybe there's something wrong in my code. I'd appreciate any help.
Below is some of my code that does the drawing:
[CustomEditor(typeof(NPCSpawnConfig))]
public class NPCSpawnEditor : Editor
{
enum SupportedAspects
{
Aspect4by3 = 1,
Aspect5by4 = 2,
Aspect16by10 = 3,
Aspect16by9 = 4
};
Camera _cam = null;
RenderTexture _rt;
Texture2D _tex2d;
Scene _scene;
// preview variables
SupportedAspects _aspectChoiceIdx = SupportedAspects.Aspect16by10;
float _curAspect;
// world space (orthographicSize)
float _worldScreenHeight = 5;
int _renderTextureHeight = 1080;
float ToFloat(SupportedAspects aspects)
{
switch(aspects)
{
case SupportedAspects.Aspect16by10:
return 16 / 10f;
case SupportedAspects.Aspect16by9:
return 16 / 9f;
case SupportedAspects.Aspect4by3:
return 4 / 3f;
case SupportedAspects.Aspect5by4:
return 5 / 4f;
default:
throw new ArgumentException();
}
}
void DrawRefScene()
{
_rt = new RenderTexture(Mathf.RoundToInt(_curAspect * _renderTextureHeight), _renderTextureHeight, 16);
_cam.targetTexture = _rt;
_cam.Render();
_tex2d = new Texture2D(_rt.width, _rt.height, TextureFormat.RGBA32, false);
_tex2d.Apply(false);
Graphics.CopyTexture(_rt, _tex2d);
}
Vector2 GetGUIPreviewSize()
{
Vector2 camSizeWorld = new Vector2(_worldScreenHeight * _curAspect, _worldScreenHeight);
float scaleFactor = EditorGUIUtility.currentViewWidth / camSizeWorld.x;
return new Vector2(EditorGUIUtility.currentViewWidth, scaleFactor * camSizeWorld.y);
}
#region Init
void OnEnable()
{
void OpenSceneDelay()
{
EditorApplication.delayCall -= OpenSceneDelay;
DrawRefScene();
}
_aspectChoiceIdx = SupportedAspects.Aspect16by10;
_scene = EditorSceneManager.NewPreviewScene();
PrefabUtility.LoadPrefabContentsIntoPreviewScene("Assets/Prefabs/Demo/DemoBkg.prefab", _scene);
_cam = _scene.GetRootGameObjects()[0].GetComponentInChildren<Camera>();
_curAspect = ToFloat(_aspectChoiceIdx);
_cam.aspect = _curAspect;
_cam.orthographicSize = _worldScreenHeight;
EditorApplication.delayCall += OpenSceneDelay;
}
void OnDisable()
{
EditorSceneManager.ClosePreviewScene(_scene);
}
#endregion
void OnCamSettingChange()
{
_curAspect = ToFloat(_aspectChoiceIdx);
_cam.aspect = _curAspect;
_cam.orthographicSize = _worldScreenHeight;
DrawRefScene();
}
// GUI states
class GUIControlStates
{
public bool foldout = false;
};
GUIControlStates _guiStates = new GUIControlStates();
public override void OnInspectorGUI()
{
// draw serializedObject fields
// ....
// display options
using (var scope = new EditorGUI.ChangeCheckScope())
{
_aspectChoiceIdx = (SupportedAspects)EditorGUILayout.EnumPopup("label", (Enum)_aspectChoiceIdx);
if (scope.changed)
{
OnCamSettingChange();
}
}
_guiStates.foldout = EditorGUILayout.Foldout(_guiStates.foldout, "label", true);
if(_guiStates.foldout)
{
using (var scope = new EditorGUI.ChangeCheckScope())
{
_worldScreenHeight = EditorGUILayout.FloatField("label", _worldScreenHeight);
_renderTextureHeight = EditorGUILayout.IntField("label", _renderTextureHeight);
if (scope.changed)
{
OnCamSettingChange();
}
}
}
if (_tex2d != null)
{
Vector2 sz = GetGUIPreviewSize();
Rect r = EditorGUILayout.GetControlRect(false,
GUILayout.Height(sz.y),
GUILayout.ExpandHeight(false));
EditorGUI.DrawPreviewTexture(r, _tex2d);
}
}
}
Here is the result: (only clear color is displayed, but the prefab contains a lot of sprites that should be drawn. The camera is also correctly positioned relative to the sprites.)
Solved this by adding the following 2 lines after getting the camera component.
_cam.cameraType = CameraType.Preview;
_cam.scene = _scene;
I'm programming a game in Unity and I need to load a static map. The map are correctly displayed in the editor, and in Android devices, but not in iOS devices. It says the url is incorrect... I don´t know what is the solution. Can anybody help me?
I call the map with this code:
url= "http://maps.google.com/maps/api/staticmap?center="+fixLat+","+fixLon+"&zoom="+zoom+"&scale=2&size=640x640&style=feature:all|element:geometry|hue:0x00fff0|lightness:0|gamma:0.21|visibility:on&style=feature:all|element:labels|visibility:off&style=feature:landscape.man_made|element:geometry|color:0x133f42|visibility:on&style=feature:landscape.natural|element:geometry.fill|visibility:on|hue:0x00ffd2|saturation:35|lightness:0|gamma:0.5&style=feature:poi|element:geometry.fill|lightness:0|gamma:0.6|visibility:on&style=feature:poi.park|element:geometry|visibility:on|saturation:0|color:0x2e9470&style=feature:road|element:geometry.fill|visibility:on|color:0x05111a&style=feature:road|element:geometry.stroke|visibility:off&style=feature:transit|element:geometry|visibility:off"+key;
This is the full code to call the url:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class Gpsconnect : MonoBehaviour
{
public Transform user;
public bool simGPS = true;
public float userSpeed = 5.0f;
public bool realSpeed = false;
public float fixLat = 42.3627f;
public float fixLon = -71.05686f;
public float altitude;
public float heading;
public float accuracy;
public int maxZoom = 18;
public int minZoom = 1;
public int zoom = 17;
private float multiplier;
public string key = "";
public string[] maptype;
public int[] mapSize;
public int index;
public int indexSize;
public float camDist = 15.0f;
public int camAngle = 40;
public int initTime = 3;
public int maxWait = 30;
public bool buttons = true;
public string dmsLat;
public string dmsLon;
public float updateRate = 0.1f;
public bool autoCenter = true;
public string status;
public bool gpsFix;
public Vector3 iniRef;
public bool info;
public bool triDView = false;
public bool ready;
public bool freeCam = false;
public bool pinchToZoom = true;
public bool dragToPan = true;
public bool mapDisabled;
public bool mapping = false;
public Transform cam;
public float userLon;
public float userLat;
private float levelHeight;
private float smooth = 1.3f;
private float yVelocity = 0.0f;
private float speed;
private Camera mycam;
private float currentOrtoSize;
private LocationInfo loc;
private Vector3 currentPosition;
private Vector3 newUserPos;
private Vector3 currentUserPos;
private float download;
private WWW www;
private string url = "";
private double longitude;
private double latitude;
private Rect rect;
private float screenX;
private float screenY;
private Renderer maprender;
private Transform mymap;
private float initPointerSize;
private double tempLat;
private double tempLon;
private bool touchZoom;
private string centre;
private bool centering;
private Texture centerIcon;
private Texture topIcon;
private Texture bottomIcon;
private Texture leftIcon;
private Texture rightIcon;
private GUIStyle arrowIcon;
private float dot;
private bool centered = true;
private int borderTile = 0;
private bool tileLeft;
private bool tileRight;
private bool tileTop;
private bool tileBottom;
private Rect topCursorPos;
private Rect rightCursorPos;
private Rect bottomCursorPos;
private Rect leftCursorPos;
void Awake(){
//Set the map's tag to GameController
transform.tag = "GameController";
cam = Camera.main.transform;
mycam = Camera.main;
user = GameObject.FindGameObjectWithTag("Player").transform;
//Store most used components and values into variables for faster access.
mymap = transform;
maprender = GetComponent<Renderer>();
screenX = Screen.width;
screenY = Screen.height;
//Add possible values to maptype and mapsize arrays (GOOGLE)
maptype = new string[]{"satellite","roadmap","hybrid","terrain"};
mapSize = new int[]{640}; //in pixels
//Set GUI "center" button label
if(triDView){
centre = "refresh";
}
//Enable autocenter on 2D-view (default)
else{
autoCenter = true;
}
//Load required interface textures
centerIcon = Resources.Load("centerIcon") as Texture2D;
topIcon = Resources.Load("cursorTop") as Texture2D;
bottomIcon = Resources.Load("cursorBottom") as Texture2D;
leftIcon = Resources.Load("cursorLeft") as Texture2D;
rightIcon = Resources.Load("cursorRight") as Texture2D;
//Resize GUI according to screen size/orientation
if(screenY >= screenX){
dot = screenY/800.0f;
}else{
dot = screenX/800.0f;
}
}
IEnumerator Start () {
//Setting variables values on Start
gpsFix=false;
rect = new Rect (screenX/10, screenY/10, 8*screenX/10, 8*screenY/10);
topCursorPos = new Rect(screenX/2-25*dot, 0, 50*dot, 50*dot);
rightCursorPos = new Rect(screenX-50*dot, screenY/2-25*dot, 50*dot, 50*dot);
if(!buttons)
bottomCursorPos = new Rect(screenX/2-25*dot, screenY-50*dot, 50*dot, 50*dot);
else
bottomCursorPos = new Rect(screenX/2-25*dot, screenY-50*dot-screenY/12, 50*dot, 50*dot);
leftCursorPos = new Rect(0, screenY/2-25*dot, 50*dot, 50*dot);
Vector3 tmp = mymap.eulerAngles;
tmp.y=180;
mymap.eulerAngles = tmp;
initPointerSize = user.localScale.x;
user.position = new Vector3(0, user.position.y, 0);
//Initial Camera Settings
//3D
if(triDView){
mycam.orthographic = false;
pinchToZoom = false;
dragToPan = false;
//Set the camera's field of view according to Screen size so map's visible area is maximized.
if(screenY > screenX){
mycam.fieldOfView = 72.5f;
}else{
mycam.fieldOfView = 95-(28*(screenX/screenY));
}
}
//2D
else{
mycam.orthographic = true;
mycam.nearClipPlane = 0.1f;
mycam.farClipPlane = cam.position.y+1;
if(screenY >= screenX){
mycam.orthographicSize = mymap.localScale.z*5.0f;
}else{
mycam.orthographicSize = (screenY/screenX)*mymap.localScale.x*5.0f;
}
}
//The "ready" variable will be true when the map texture has been successfully loaded.
ready = false;
//STARTING LOCATION SERVICES
// First, check if user has location service enabled
#if (UNITY_IOS && !UNITY_EDITOR)
if (!Input.location.isEnabledByUser){
//This message prints to the Editor Console
print("Ha sido imposible iniciar los servicios de localizacion.\nComprueba los ajustes de localización de tu teléfono");
//You can use this "status" variable to show messages in your custom user interface (GUIText, etc.)
status = "Ha sido imposible iniciar \nlos servicios de localizacion.\nComprueba los ajustes de \nlocalización de tu teléfono";
yield return new WaitForSeconds(4);
Application.LoadLevel("0_Login");
}
#endif
// Start service before querying location
Input.location.Start (3.0f, 3.0f);
Input.compass.enabled = true;
print("Iniciando servicios de localización...");
status = "Iniciando servicios de localización...";
// Wait until service initializes
while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) {
yield return new WaitForSeconds (1);
maxWait--;
}
// Service didn't initialize in 30 seconds
if (maxWait < 1) {
print("Ha sido imposible iniciar los servicios de localizacion.\nComprueba los ajustes de localización de tu teléfono");
status = "Ha sido imposible iniciar \nlos servicios de localizacion.\nComprueba los ajustes de \nlocalización de tu teléfono";
yield return new WaitForSeconds(4);
Application.LoadLevel("0_Login");
}
// Connection has failed
if (Input.location.status == LocationServiceStatus.Failed) {
print("Ha sido imposible determinar tu localización\nComprueba los ajustes de localización de tu teléfono");
status = "Ha sido imposible determinar \ntu localización.\nComprueba los ajustes de \nlocalización de tu teléfono";
yield return new WaitForSeconds(4);
Application.LoadLevel("0_Login");
}
// Access granted and location value could be retrieved
else {
if(!mapDisabled){
print("GPS conectado. Ajustando posición...");
status = "GPS conectado!\n Ajustando posición...";
}
else{
print("GPS conectado.");
status = "GPS conectado!";
}
if(!simGPS){
//Wait in order to find enough satellites and increase GPS accuracy
yield return new WaitForSeconds(initTime);
//Set position
loc = Input.location.lastData;
iniRef.x = ((loc.longitude*20037508.34f/180)/100);
iniRef.z = (float)(System.Math.Log(System.Math.Tan((90+loc.latitude)*System.Math.PI/360))/(System.Math.PI/180));
iniRef.z = ((iniRef.z*20037508.34f/180)/100);
iniRef.y = 0;
fixLon = loc.longitude;
fixLat = loc.latitude;
//Successful GPS fix
gpsFix = true;
//Update Map for the current location
StartCoroutine(MapPosition());
}
else{
//Simulate initialization time
yield return new WaitForSeconds(initTime);
//Set Position
iniRef.x = ((fixLon*20037508.34f/180)/100);
iniRef.z = (float)(System.Math.Log(System.Math.Tan((90+fixLat)*System.Math.PI/360))/(System.Math.PI/180));
iniRef.z = (iniRef.z*20037508.34f/180)/100;
iniRef.y = 0;
//Simulated successful GPS fix
gpsFix = true;
//Update Map for the current location
StartCoroutine(MapPosition());
}
}
//Rescale map, set new camera height, and resize user pointer according to new zoom level
StartCoroutine(ReScale());
//Set player's position using new location data (every "updateRate" seconds)
//Default value for updateRate is 0.1. Increase if necessary to improve performance
InvokeRepeating("MyPosition", 1, updateRate);
//Read incoming compass data (every 0.1s)
InvokeRepeating("Orientate", 1, 0.1f);
//Get altitude and horizontal accuracy readings using new location data (Default: every 2s)
InvokeRepeating("AccuracyAltitude", 1, 2);
//Auto-Center Map on 2D View Mode
InvokeRepeating("Check", 1, 0.2f);
}
void MyPosition(){
if(gpsFix){
if(!simGPS){
loc = Input.location.lastData;
newUserPos.x = ((loc.longitude*20037508.34f/180)/100)-iniRef.x;
newUserPos.z = (float)(System.Math.Log(System.Math.Tan((90+loc.latitude)*System.Math.PI/360))/(System.Math.PI/180));
newUserPos.z = ((newUserPos.z*20037508.34f/180)/100)-iniRef.z;
dmsLat = convertdmsLat(loc.latitude);
dmsLon = convertdmsLon(loc.longitude);
userLon = loc.longitude;
userLat = loc.latitude;
}
else{
userLon = (18000*(user.position.x+iniRef.x))/20037508.34f;
userLat = ((360/Mathf.PI)*Mathf.Atan(Mathf.Exp(0.00001567855943f*(user.position.z+iniRef.z))))-90;
dmsLat = convertdmsLat(userLat);
dmsLon = convertdmsLon(userLon);
}
}
}
void Orientate(){
if(!simGPS && gpsFix){
heading = Input.compass.trueHeading;
}
else{
heading = user.eulerAngles.y;
}
}
void AccuracyAltitude(){
if(gpsFix)
altitude = loc.altitude;
accuracy = loc.horizontalAccuracy;
}
void Check(){
if(autoCenter && triDView == false){
if(ready == true && mapping == false && gpsFix){
if (rect.Contains(Vector2.Scale(mycam.WorldToViewportPoint (user.position), new Vector2(screenX, screenY)))){
//DoNothing
}
else{
centering=true;
StartCoroutine(MapPosition());
StartCoroutine(ReScale());
}
}
}
}
//Auto-Center Map on 3D View Mode when exiting map's collider
void OnTriggerExit(Collider other){
if(other.tag == "Player" && autoCenter && triDView){
StartCoroutine(MapPosition());
StartCoroutine(ReScale());
}
}
//Update Map with the corresponding map images for the current location ============================================
IEnumerator MapPosition(){
//The mapping variable will only be true while the map is being updated
mapping = true;
CursorsOff();
//CHECK GPS STATUS AND RESTART IF NEEDED
if (Input.location.status == LocationServiceStatus.Stopped || Input.location.status == LocationServiceStatus.Failed){
// Start service before querying location
Input.location.Start (3.0f, 3.0f);
// Wait until service initializes
int maxWait = 20;
while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) {
yield return new WaitForSeconds (1);
maxWait--;
}
// Service didn't initialize in 20 seconds
if (maxWait < 1) {
print ("Timed out");
//use the status string variable to print messages to your own user interface (GUIText, etc.)
status = "Timed out";
}
// Connection has failed
if (Input.location.status == LocationServiceStatus.Failed) {
print ("Unable to determine device location");
//use the status string variable to print messages to your own user interface (GUIText, etc.)
status = "Unable to determine device location";
}
}
//------------------------------------------------------------------ //
www = null;
//Get last available location data
loc = Input.location.lastData;
//Make player invisible while updating map
user.gameObject.GetComponent<Renderer>().enabled = false;
//Set target latitude and longitude
if(triDView){
if(simGPS){
fixLon = (18000*(user.position.x+iniRef.x))/20037508.34f;
fixLat = ((360/Mathf.PI)*Mathf.Atan(Mathf.Exp(0.00001567855943f*(user.position.z+iniRef.z))))-90;
}else{
fixLon = loc.longitude;
fixLat = loc.latitude;
}
}else{
if(centering){
if(simGPS){
fixLon = (18000*(user.position.x+iniRef.x))/20037508.34f;
fixLat = ((360/Mathf.PI)*Mathf.Atan(Mathf.Exp(0.00001567855943f*(user.position.z+iniRef.z))))-90;
}else{
fixLon = loc.longitude;
fixLat = loc.latitude;
}
}
else{
if(borderTile == 0){
fixLat = ((360/Mathf.PI)*Mathf.Atan(Mathf.Exp(0.00001567855943f*(cam.position.z+iniRef.z))))-90;
fixLon = (18000*(cam.position.x+iniRef.x))/20037508.34f;
}
//North tile
if (borderTile == 1){
fixLat = ((360/Mathf.PI)*Mathf.Atan(Mathf.Exp(0.00001567855943f*(cam.position.z+3*mycam.orthographicSize/2+iniRef.z))))-90;
fixLon = (18000 *(cam.position.x+iniRef.x))/20037508.34f;
borderTile=0;
tileTop=false;
}
//East Tile
if (borderTile == 2){
fixLat = ((360/Mathf.PI)*Mathf.Atan(Mathf.Exp(0.00001567855943f*(cam.position.z+iniRef.z))))-90;
fixLon = (18000*(cam.position.x+3*(screenX*mycam.orthographicSize/screenY)/2+iniRef.x))/20037508.34f;
borderTile = 0;
}
//South Tile
if (borderTile == 3){
fixLat = ((360/Mathf.PI)*Mathf.Atan(Mathf.Exp(0.00001567855943f*(cam.position.z-3*mycam.orthographicSize/2+iniRef.z))))-90;
fixLon = (18000*(cam.position.x+iniRef.x))/20037508.34f;
borderTile=0;
}
//West Tile
if (borderTile == 4){
fixLat = ((360/Mathf.PI)*Mathf.Atan(Mathf.Exp(0.00001567855943f*(cam.position.z+iniRef.z))))-90;
fixLon = (18000*(cam.position.x-3*(screenX*mycam.orthographicSize/screenY)/2+iniRef.x))/20037508.34f;
borderTile=0;
}
}
}
//MAP ================================================================================
//Build a valid Google Maps tile request for the current location
url= "https://maps.google.com/maps/api/staticmap?center="+fixLat+","+fixLon+"&zoom="+zoom+"&scale=2&size=640x640&style=feature:all|element:geometry|hue:0x00fff0|lightness:0|gamma:0.21|visibility:on&style=feature:all|element:labels|visibility:off&style=feature:landscape.man_made|element:geometry|color:0x133f42|visibility:on&style=feature:landscape.natural|element:geometry.fill|visibility:on|hue:0x00ffd2|saturation:35|lightness:0|gamma:0.5&style=feature:poi|element:geometry.fill|lightness:0|gamma:0.6|visibility:on&style=feature:poi.park|element:geometry|visibility:on|saturation:0|color:0x2e9470&style=feature:road|element:geometry.fill|visibility:on|color:0x05111a&style=feature:road|element:geometry.stroke|visibility:off&style=feature:transit|element:geometry|visibility:off"+"&sensor=false&key="+key;
tempLat = fixLat;
tempLon = fixLon;
//=================================================================================================
//Proceed with download if a Wireless internet connection is available
if(Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork){
StartCoroutine(Online());
}
//Proceed with download if a 3G/4G internet connection is available
else if(Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork){
StartCoroutine(Online());
}
//No internet connection is available. Switching to Offline mode.
else{
Offline();
}
}
//ONLINE MAP DOWNLOAD
IEnumerator Online(){
if(!mapDisabled){
// Start a download of the given URL
www = new WWW(url);
// Wait for download to complete
download = (www.progress);
while(!www.isDone){
print("Actualizando mapa "+System.Math.Round(download*100)+" %");
//use the status string variable to print messages to your own user interface (GUIText, etc.)
status="Actualizando mapa "+System.Math.Round(download*100)+" %";
yield return null;
}
//Show download progress and apply texture
if(www.error == null){
print("Actualizando mapa 100 %");
print("Mapa preparado!");
//use the status string variable to print messages to your own user interface (GUIText, etc.)
status = "Actualizando mapa 100 %\nMapa preparado!";
yield return new WaitForSeconds (0.5f);
maprender.material.mainTexture = null;
Texture2D tmp;
tmp = new Texture2D(1280, 1280, TextureFormat.RGB24, false);
maprender.material.mainTexture = tmp;
www.LoadImageIntoTexture(tmp);
}
//Download Error. Switching to offline mode
else{
print("Error en el mapa:"+www.error);
//use the status string variable to print messages to your own user interface (GUIText, etc.)
status = "Error en el mapa:"+www.error;
yield return new WaitForSeconds (4);
maprender.material.mainTexture = null;
Offline();
}
maprender.enabled = true;
}
ReSet();
user.gameObject.GetComponent<Renderer>().enabled = true;
ready = true;
mapping = false;
}
//USING OFFLINE BACKGROUND TEXTURE
void Offline(){
if(!mapDisabled){
maprender.material.mainTexture=Resources.Load("offline") as Texture2D;
maprender.enabled = true;
}
ReSet();
ready = true;
mapping = false;
user.gameObject.GetComponent<Renderer>().enabled = true;
}
//Re-position map and camera using updated data
void ReSet(){
Vector3 tmp = transform.position;
tmp.x = (float)((tempLon*20037508.34f/180)/100)-iniRef.x;
tmp.z = (float)(System.Math.Log(System.Math.Tan((90+tempLat)*System.Math.PI/360))/(System.Math.PI/180));
tmp.z = ((tmp.z*20037508.34f/180)/100)-iniRef.z;
transform.position = tmp;
if(!freeCam){
cam.position = new Vector3(transform.position.x, cam.position.y, transform.position.z);
}
if(triDView == false && centering){
centered = true;
autoCenter = true;
centering = false;
}
}
void Update(){
//Rename GUI "center" button label
if(!triDView){
if(cam.position.x != user.position.x || cam.position.z != user.position.z)
centre ="center";
else
centre ="refresh";
}
//User pointer speed
if(realSpeed){
speed = userSpeed*0.05f;
}
else{
speed = userSpeed*10000/(Mathf.Pow(2, zoom)*1.0f);
}
//3D-2D View Camera Toggle (use only while game is stopped)
if(triDView && !freeCam){
cam.parent = user;
if(ready)
cam.LookAt(user);
}
if(ready){
if(!simGPS){
//Smoothly move pointer to updated position
currentUserPos.x = user.position.x;
currentUserPos.x = Mathf.Lerp (user.position.x, newUserPos.x, 2.0f*Time.deltaTime);
currentUserPos.z = user.position.z;
currentUserPos.z = Mathf.Lerp (user.position.z, newUserPos.z, 2.0f*Time.deltaTime);
user.position = new Vector3(currentUserPos.x, user.position.y, currentUserPos.z);
//Update rotation
if(System.Math.Abs(user.eulerAngles.y-heading) >= 5){
float newAngle = Mathf.SmoothDampAngle(user.eulerAngles.y, heading, ref yVelocity, smooth);
user.eulerAngles = new Vector3(user.eulerAngles.x, newAngle, user.eulerAngles.z);
}
}
else{
//When GPS Emulator is enabled, user position is controlled by keyboard input.
if(mapping == false){
//Use keyboard input to move the player
if (Input.GetKey ("up") || Input.GetKey ("w")){
user.transform.Translate(Vector3.forward*speed*Time.deltaTime);
}
if (Input.GetKey ("down") || Input.GetKey ("s")){
user.transform.Translate(-Vector3.forward*speed*Time.deltaTime);
}
//rotate pointer when pressing Left and Right arrow keys
user.Rotate(Vector3.up, Input.GetAxis("Horizontal")*80*Time.deltaTime);
}
}
}
if(mapping && !mapDisabled){
//get download progress while images are still downloading
if(www != null)
download = www.progress;
}
//Enable/Disable map renderer
if(mapDisabled)
maprender.enabled = false;
else
maprender.enabled = true;
void CheckBorders(){
//Reached left tile border
if(Mathf.Round((mycam.ScreenToWorldPoint(new Vector3(0, 0.5f, cam.position.y)).x)*100.0f)/100.0f <= Mathf.Round((mymap.position.x-mymap.localScale.x*5)*100.0f)/100.0f){
//show button for borderTile=4;
tileLeft = true;
}else{
//hide button
tileLeft = false;
}
//Reached right tile border
if(Mathf.Round((mycam.ScreenToWorldPoint(new Vector3(mycam.pixelWidth, 0.5f, cam.position.y)).x)*100.0f)/100.0f >= Mathf.Round((mymap.position.x+mymap.localScale.x*5)*100.0f)/100.0f){
//show button for borderTile=2;
tileRight = true;
}else{
//hide button
tileRight = false;
}
//Reached bottom tile border
if(Mathf.Round((mycam.ScreenToWorldPoint(new Vector3(0.5f, 0, cam.position.y)).z)*100.0f)/100.0f <= Mathf.Round((mymap.position.z-mymap.localScale.z*5)*100.0f)/100.0f){
//show button for borderTile=3;
tileBottom = true;
}else{
//hide button
tileBottom = false;
}
//Reached top tile border
if(Mathf.Round((mycam.ScreenToWorldPoint(new Vector3(0.5f, mycam.pixelHeight, cam.position.y)).z)*100.0f)/100.0f >= Mathf.Round((mymap.position.z+mymap.localScale.z*5)*100.0f)/100.0f){
//show button for borderTile=1;
tileTop = true;
}else{
//hide button
tileTop = false;
}
}
//Disable surrounding tiles cursors
void CursorsOff(){
tileTop = false;
tileBottom = false;
tileLeft = false;
tileRight = false;
}
//Clamp the camera position
void ClampCam(){
Vector3 tmp = cam.position;
tmp.x = Mathf.Clamp(cam.position.x,
mymap.position.x-(mymap.localScale.x*5)+(mycam.ScreenToWorldPoint(new Vector3(mycam.pixelWidth, 0.5f, cam.position.y)).x-mycam.ScreenToWorldPoint(new Vector3(0, 0.5f, cam.position.y)).x)/2,
mymap.position.x+(mymap.localScale.x*5)-(mycam.ScreenToWorldPoint(new Vector3(mycam.pixelWidth, 0.5f, cam.position.y)).x-mycam.ScreenToWorldPoint(new Vector3(0, 0.5f, cam.position.y)).x)/2 );
tmp.z = Mathf.Clamp(cam.position.z,
mymap.position.z-(mymap.localScale.z*5)+(mycam.ScreenToWorldPoint(new Vector3(0.5f, mycam.pixelHeight, cam.position.y)).z-mycam.ScreenToWorldPoint(new Vector3(0.5f, 0, cam.position.y)).z)/2,
mymap.position.z+(mymap.localScale.z*5)-(mycam.ScreenToWorldPoint(new Vector3(0.5f, mycam.pixelHeight, cam.position.y)).z-mycam.ScreenToWorldPoint(new Vector3(0.5f, 0, cam.position.y)).z)/2 );
cam.position = tmp;
}
}
Those are the screenshots.
Editor and Android device
iOS device
Ran the code in your question and was able to replicate your problem. This is happening due to new restriction on using http connections instead of https on iOS. Just like I mentioned in my comment, replacing WWW with UnityWebRequest solved this problem.
Also, you are unnecessarily creating new textures each time with new Texture2D(1280, 1280, TextureFormat.RGB24, false); is executed. This should be done with Unity's UI Component RawImage. In this case, no unnecessary memory allocation.
All you have to do to the code in your question is to remove the WWW API and use UnityWebRequest. Also remove Renderer or Texture2D and use RawImage to display your map. Below is a simple test script I used to test this. It runs on the both Editor,iOS and possibly all other platforms.
public class Gpsconnect : MonoBehaviour
{
public RawImage imageDisp;
public float fixLat = 42.3627f;
public float fixLon = -71.05686f;
public int zoom = 4;
public string key = "";
public Vector3 iniRef;
public Transform cam;
private Camera mycam;
private string url = "";
//Update Map with the corresponding map images for the current location ============================================
IEnumerator load()
{
yield return null;
mycam = Camera.main;
fixLat = ((360 / Mathf.PI) * Mathf.Atan(Mathf.Exp(0.00001567855943f * (cam.position.z - 3 * mycam.orthographicSize / 2 + iniRef.z)))) - 90;
fixLon = (18000 * (cam.position.x + iniRef.x)) / 20037508.34f;
//MAP ================================================================================
//Build a valid Google Maps tile request for the current location
url = "https://maps.google.com/maps/api/staticmap?center=" + fixLat + "," + fixLon + "&zoom=" + zoom + "&scale=2&size=640x640&style=feature:all|element:geometry|hue:0x00fff0|lightness:0|gamma:0.21|visibility:on&style=feature:all|element:labels|visibility:off&style=feature:landscape.man_made|element:geometry|color:0x133f42|visibility:on&style=feature:landscape.natural|element:geometry.fill|visibility:on|hue:0x00ffd2|saturation:35|lightness:0|gamma:0.5&style=feature:poi|element:geometry.fill|lightness:0|gamma:0.6|visibility:on&style=feature:poi.park|element:geometry|visibility:on|saturation:0|color:0x2e9470&style=feature:road|element:geometry.fill|visibility:on|color:0x05111a&style=feature:road|element:geometry.stroke|visibility:off&style=feature:transit|element:geometry|visibility:off" + "&sensor=false&key=" + key;
UnityWebRequest www = UnityWebRequest.GetTexture(url);
yield return www.Send();
Debug.Log("Done: ");
if (www.isError)
{
Debug.Log("Error while downloading image: " + www.error);
}
else
{
imageDisp.texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
}
}
void Start()
{
StartCoroutine(load());
}
}
I'm trying to display a simple rectangle right in front of my OVRPlayerController's camera but it seems to be impossible.
I think it might have something to do with the fact that Rect is 2D and my environment is 3D. Does that make sense?
The code is the following (I have ommited the unnecessary stuff):
static int MAX_MENU_OPTIONS = 3;
public GameObject Menu;
private bool showMenu = false;
private float menuIndex = 0;
private bool hasPressedDirectionalPad = false;
public Transform[] buttons = new Transform[MAX_MENU_OPTIONS];
private static Texture2D staticRectTexture;
private static GUIStyle staticRectStyle;
bool DpadIsPressed() {
if (!hasPressedDirectionalPad && Input.GetAxis("DpadY") != 0 && hasPressedDirectionalPad == false){
menuIndex += Mathf.Sign(Input.GetAxis("DpadY")) * (-1);
if (menuIndex < 0) menuIndex = 0;
else if (menuIndex > MAX_MENU_OPTIONS-1) menuIndex = MAX_MENU_OPTIONS-1;
hasPressedDirectionalPad = true;
}
if(Input.GetAxis("DpadY") == 0){
hasPressedDirectionalPad = false;
}
return hasPressedDirectionalPad;
}
void Start() {
Menu.SetActive(false);
staticRectTexture = new Texture2D(1, 1, TextureFormat.RGB24, true);
staticRectStyle = new GUIStyle();
}
void Update() {
if (Input.GetButtonDown("A")) {
DoAction ();
print ("A key was pressed");
}
if (Input.GetButtonDown("Options")) {
showMenu = !showMenu;
if (showMenu) {
Time.timeScale = 0;
menuIndex = 0;
Menu.transform.rotation = this.transform.rotation;
Menu.transform.position = this.transform.position;
} else
Time.timeScale = 1;
}
if (DpadIsPressed ()) {
print ("Dpad key was pressed and menuIndex = " + menuIndex);
}
if (showMenu) {
Menu.SetActive (true);
}
if (!showMenu) {
Menu.SetActive (false);
}
}
void OnGUI() {
if (showMenu) {
Vector3 offset = new Vector3(0, 0, 0.2f);
Vector3 posSelectRectangle = buttons[(int)menuIndex].transform.position + offset;
Rect selectionRectangle = new Rect(posSelectRectangle.x - (float)177/2,
posSelectRectangle.y - (float)43/2,
177.0f, 43.0f);
GUIDrawRect(selectionRectangle, new Color(255.0f, 0, 0));
}
}
void DoAction () {
if (menuIndex == 0)
Salir ();
/*else if (menuIndex == 1)
Guardar ();*/
else if (menuIndex == 2)
Salir ();
}
public static void GUIDrawRect(Rect position, Color color ) {
staticRectTexture.SetPixel( 0, 0, color );
staticRectTexture.Apply();
staticRectStyle.normal.background = staticRectTexture;
GUI.Box( position, GUIContent.none, staticRectStyle );
}
The functions are visited, but the rectangle doesn't show up. Do you see the mistake? Maybe it has something to do with the Oculus Rift?
OnGUI and Screen-space Canvas are not supported in VR mode. This is because there is no way to handle stereoscopic rendering. (Note: They will render to the duplicate display on the user's PC though).
If you want to render in front of the user's camera (like a HUD), you can:
Use a Canvas:
Create a canvas, then add your UI, and set the canvas in world-space. Parent the canvas to the VR Camera game object, and scale it down (it defaults to very very big) and rotate it so it faces the camera.
Or, Use 3D:
Create a 3d Object (Plane, Cube, Quad, whatever!) and parent it to your VR Camera. You can use standard 3d techniques to update it's texture or render texture.
I have a scene in which the player can pick up and drop objects, as well as move and look around.
All player objects are children of an empty game object "MainCharacter":
MainCharacter >
Capsule (With RigidBody and PlayerMoveScript) >
PlayerBase (empty - used for checking if grounded)
MainCamera >
Hands(With PickUpDrop script)
The object I pick up Lerps to my Hands position, however after my capsule collides with any walls there is a strange jittering which I cannot work out how to fix!!
Heres the .exe:GameTest
Heres the data folder : Data
Here are the scripts:
Pick Up and Drop Script:
public bool handsFull = false;
public float distanceMax = 20f;
public Transform handPosition;
public LayerMask canPickUp;
public GameObject taggedGameObject;
public bool colliderTriggered;
public bool bounds;
public PickedUpObject pickedUpScript;
public Rigidbody player;
// Use this for initialization
void Start () {
print(FindClosestPickup().name);
handPosition = transform;
pickedUpScript = null;
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.E) && !bounds) {
if (Physics.CheckSphere (handPosition.position, 2f, canPickUp)) {
if (handsFull) {
Drop ();
}
if (!handsFull) {
PickedUp ();
}
handsFull = !handsFull;
}
}
if (handsFull) {
RotateMovePickedUpObject();
}
}
private void PickedUp(){
//Closest object to top of list
taggedGameObject = (GameObject)FindClosestPickup();
taggedGameObject.collider.isTrigger = true;
taggedGameObject.rigidbody.useGravity = false;
taggedGameObject.rigidbody.isKinematic = true;
pickedUpScript = taggedGameObject.GetComponent<PickedUpObject> ();
Debug.Log ("Pick Up");
}
private void RotateMovePickedUpObject(){
//Rotate
if(Input.GetKeyDown(KeyCode.End)){
taggedGameObject.transform.localRotation *= Quaternion.Euler(0, 0, 45);
}
if(Input.GetKeyDown(KeyCode.Delete)){
taggedGameObject.transform.localRotation *= Quaternion.Euler(0, 45, 0);
}
if(Input.GetKeyDown(KeyCode.PageDown)){
taggedGameObject.transform.localRotation *= Quaternion.Euler(0, -45, 0);
}
if(Input.GetKeyDown(KeyCode.Home)){
taggedGameObject.transform.localRotation *= Quaternion.Euler(0, 0, -45);
}
if(Input.GetKeyDown(KeyCode.PageUp)){
taggedGameObject.transform.localRotation *= Quaternion.Euler(-45, 0, 0);
}
if(Input.GetKeyDown(KeyCode.Insert)){
taggedGameObject.transform.localRotation *= Quaternion.Euler(45, 0, 0);
}
taggedGameObject.transform.position = Vector3.Lerp(taggedGameObject.transform.position, handPosition.position, (1 - Mathf.Exp( -20 * Time.smoothDeltaTime )) * 10);
}
private void Drop(){
taggedGameObject.collider.isTrigger = false;
taggedGameObject.rigidbody.useGravity = true;
taggedGameObject.rigidbody.isKinematic = false;
taggedGameObject = null;
Debug.Log ("Drop");
pickedUpScript = null;
}
private GameObject FindClosestPickup() {
//Find closest gameobject with tag
GameObject[] gos;
gos = GameObject.FindGameObjectsWithTag("pickup");
GameObject closest = null;
float distance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (GameObject go in gos) {
Vector3 diff = go.transform.position - position;
float curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = go;
distance = curDistance;
}
}
return closest;
}
}
The Picked Up Objects Script:
public PickUpDrop pickUpScript;
public GameObject thisOne;
public Color thecolor;
public bool inObject;
// Use this for initialization
void Start () {
thisOne = this.gameObject;
}
// Update is called once per frame
void Update ()
{
thecolor = thisOne.renderer.material.color;
if (pickUpScript.taggedGameObject != thisOne)
{
gameObject.renderer.material.color = Color.gray;
}
if (pickUpScript.taggedGameObject == thisOne)
{
Color color = renderer.material.color;
color.a = 0.5f;
renderer.material.color = color;
}
}
void OnTriggerEnter ()
{
if (thisOne == pickUpScript.taggedGameObject)
{
inObject = true;
pickUpScript.bounds = true;
gameObject.renderer.material.color = Color.red;
}
}
void OnTriggerExit()
{
if(thisOne == pickUpScript.taggedGameObject)
{
inObject = false;
pickUpScript.bounds = false;
gameObject.renderer.material.color = Color.gray;
}
}
}
taggedGameObject.transform.position = Vector3.Lerp(taggedGameObject.transform.position, handPosition.position, (1 - Mathf.Exp( -20 * Time.smoothDeltaTime )) * 10);
This line will keep moving the object towards the hand's position. If you have a rigidbody attached to the game object you're moving then the physics acting on that object during the physics calculation will conflict with the manual movement of the object during the Update function.
It depends on what you would like to happen when this conflict occurs as to the solution. If you simply want the 'jittering' to stop and still be able to hold objects against other physical objects, then use this;
taggedGameObject.rigidbody.AddForce( ( taggedGameObject.transform.position - handPosition.position ) * force );
This will keep all interactions with the rigidbody. You'll have to tweak the force you move the object with, and perhaps disable gravity on the tagged game object while it's in the players hands. But it should have the desired effect.