Code:
IEnumerator PickImage (int maxSize)
{
Texture2D texture = null;
NativeGallery.Permission permission = NativeGallery.GetImageFromGallery (( path) => {
Debug.Log ("Image path: " + path);
if (path != null) {
// Create Texture from selected image
texture = NativeGallery.LoadImageAtPath (path, maxSize);
if (texture == null) {
Debug.Log ("Couldn't load texture from " + path);
return;
}
profileImage.sprite = Sprite.Create (texture, new Rect (0f, 0f, texture.width, texture.height), new Vector2 (0.5f, 0.5f), 100f);
}
}, "Select an image", "image/*", maxSize);
if (texture != null) {
// make texture read and write able
Texture2D readableTexture = DuplicateTexture(texture);
Debug.Log ("readable texture width: " + readableTexture.width + " height: " + readableTexture.height);
WWWForm form = new WWWForm ();
Debug.Log ("player id: " + DataCollection.localPlayer.PlayerId);
form.AddField (GameConstants.ARG_UPLOAD_PHOTO_PLAYER_ID, DataCollection.localPlayer.PlayerId);
form.AddBinaryData (GameConstants.ARG_UPLOAD_PHOTO, readableTexture.GetRawTextureData (), "profilepic.jpg", "image/*");
Dictionary<string,string> headerDisc = form.headers;
WWW www = new WWW (GameConstants.API_UPLOAD_PHOTO, form.data, headerDisc);
yield return www;
if (www.error == null) {
Debug.Log ("Data: " + www.text);
profileImage.sprite = Sprite.Create (texture, new Rect (0f, 0f, texture.width, texture.height), new Vector2 (0.5f, 0.5f), 100f);
} else {
Debug.Log ("Error: " + www.error);
}
}
Debug.Log ("Permission result: " + permission);
}
Related
I am using the following to download assetbundle and it works in first scene. But when in second scene, the same code doesn't work - the uwr.downloadedbytes return 0. If I restart the app and go straight to the second scene, it works. Strange things is when I go back to the first scene from second scene, the code works as well. I want to know what is going wrong, is it something to do with unload(false) in the first scene?
private IEnumerator DownloadBundles()
{
AssetBundleList = new List<string>();
m_AssetBundle = new List<AssetBundle>();
m_InstantiatedModels = new List<GameObject>();
yield return StartCoroutine(DownloadBundle(1));
}
private IEnumerator DownloadBundle(int i)
{
string platform = "Android";
string bundleURL = data.url + data.id + "/" + platform + "/" + data.id + "assetbundles" + i.ToString();
using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle(bundleURL, (uint)data.assetBundleVersion, 0))
{
AsyncOperation asyncOp = uwr.SendWebRequest();
while (!asyncOp.isDone)
{
if (m_ProgressText.gameObject.activeSelf)
{
m_ProgressText.text = "Loading " + (i == 1 ? "" : "More ") + "Models... " + ((int)(asyncOp.progress * 100)).ToString() + "%";
}
yield return null;
}
if (uwr.error != null)
{
throw new UnityException("AssetBundle DownloadHandler had an error: " + uwr.error);
}
else
{
Debug.Log(uwr.downloadedBytes.ToString());
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
string[] assetBundleList1 = bundle.GetAllAssetNames();
assetBundleDownloaded.Add(i);
object[] golist = bundle.LoadAllAssets();
for (int k = 0; k < golist.Length; k++)
{
GameObject go = Instantiate(golist[k] as GameObject, Vector3.zero, Quaternion.identity);
go.SetActive(false);
m_InstantiatedModels.Add(go);
}
m_AssetBundle.Add(bundle);
yield return null;
}
}
}
roadTopStartX = Random.Range(5, 10); // Path's x position which creation begins
roadTopStartY = Random.Range(8, 12); // Path's y position which creation begins
roadTopLength = Random.Range(4, 9); // Path's length
for (int i = 0; i < roadTopLength; i++)
{
GameObject tile = GameObject.Find("Tile" + (roadTopStartX + i) + " " + roadTopStartY); //I created grid whose tile's name Tile X Y like Tile 0 0
GameObject road = Instantiate(roadPrefab, tile.transform.position, tile.transform.rotation);
road.name = "Road"+ " " + (roadTopStartX + i) + " " + roadTopStartY;
roads.Add(road);
}
It is how i create random path on 2d grid, do you know better solution because when thinks become more complex gameobject.find becomes suffer for me
i found a more reliable solution: (thanks to derHugo)
public GameObject findTile(int x,int y)
{
GameObject findTilex = GameObject.Find("Tile" + (tileX + x) + " " +
(tileY + y));
return findTilex;
}
Example how i get neighbour tiles
public void getNeighbours()
{
if (findTile(0, 1) != null)
{
upper = findTile(0, 1);
}
if (findTile(0, -1) != null)
{
below = findTile(0, -1);
}
if (findTile(1, 0) != null)
{
right = findTile(1, 0);
}
if (findTile(-1, 0) != null)
{
left = findTile(-1, 0);
}
if (findTile(1, 1) != null)
{
rightCrossTop = findTile(1, 1);
}
if (findTile(1, -1) != null)
{
rightCrossUnder = findTile(1, -1);
}
if (findTile(-1, 1) != null)
{
leftCrossTop = findTile(-1, 1);
}
if (findTile(-1, -1) != null)
{
leftCrossBottom = findTile(-1, -1);
}
}
I want to make a spinning spike to move around a platform made out of tiles like in the following
I have written every possible state on where to move when platform tiles block the spike's way. It would look something like this
for (int i = 0; i < platformTileMap.Length; i++)
{
if (platformTileMap[i].HasTile(cellPosition + new Vector3Int(0, -1, 0))) // BOTTOM
{
moveX = moveDir;
}
else if (platformTileMap[i].HasTile(cellPosition + new Vector3Int(0, 1, 0))) // TOP
{
moveX = -moveDir;
}
else if (platformTileMap[i].HasTile(cellPosition + new Vector3Int(-1, -1, 0))) //BOT LEFT
{
if (moveDir == 1)
{
moveY = -1;
}
else moveX = moveDir;
}
else if (platformTileMap[i].HasTile(cellPosition + new Vector3Int(1, 1, 0))) //TOP RIGHT
{
if (moveDir == 1)
{
moveY = 1;
}
else moveX = -moveDir;
}
else if (platformTileMap[i].HasTile(cellPosition + new Vector3Int(1, -1, 0))) // BOT RIGHT
{
if (moveDir == 1)
{
moveX = moveDir;
}
else
{
moveY = -1;
}
}
else if (platformTileMap[i].HasTile(cellPosition + new Vector3Int(-1, 1, 0))) // TOP LEFT
{
if (moveDir == -1)
{
moveY = 1;
}
else
{
moveX = -moveDir;
}
}
I feel like there has to be a more efficient way to solve this. Do I really have to write every possibility in if statements? Can I achieve this with pathfinding?
How about this
Use raycast
Place Empty GameObject and rotate spike when it arrives them
You could create an array of points to move to.
public Vector3[] movePoints;
You can set movePoints in inspector or in code (such as Start function) user choice
In the update loop lerp to the next point in sequence, when arrived pull the next point, unless we are at the end of the array then pull the first point in the array, rinse and repeat forever.
https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html
Set this up properly once, when you make more blades and different configurations or want to change speed it will be ez pz.
For anyone interested. Here is how i solved it:
GridLayout platformGridLayout;
Grid platformGrid;
Tilemap[] platformTileMap;
[SerializeField] float rotationSpeed;
[SerializeField] float moveSpeed;
[SerializeField] private LayerMask platformLayerMask;
Vector3Int startPos;
Vector3Int currentCellPosition;
Vector3 raycastPlatformDir;
Vector3 raycastMoveDir;
float platformRaycastDist;
// Start is called before the first frame update
void Start()
{
movePoints = new List<Vector3Int>();
platformGridLayout = transform.parent.GetComponentInParent<GridLayout>();
platformGrid = transform.parent.GetComponentInParent<Grid>();
startPos = platformGridLayout.WorldToCell(transform.position);
Debug.Log("Cell Startposition: " + startPos);
PlatformToMoveOn();
GetStartRaycastDir();
platformRaycastDist = platformGridLayout.cellSize.x;
Debug.Log("CellCenterToWorld of Startposition: " + platformGrid.GetCellCenterWorld(startPos));
Debug.Log(platformGrid.GetCellCenterLocal(currentCellPosition + Vector3Int.FloorToInt(raycastPlatformDir) + Vector3Int.FloorToInt(raycastMoveDir)));
}
private void PlatformToMoveOn()
{
platformTileMap = new Tilemap[2];
platformTileMap[0] = GameObject.Find("Platform").GetComponent<Tilemap>();
platformTileMap[1] = GameObject.Find("MovingPlatform").GetComponent<Tilemap>();
}
private void GetStartRaycastDir()
{
for (int i = 0; i < platformTileMap.Length; i++)
{
if (platformTileMap[i].HasTile(startPos + new Vector3Int(0, -1, 0))) // BOTTOM
{
raycastPlatformDir = Vector3.down;
}
else if (platformTileMap[i].HasTile(startPos + new Vector3Int(0, 1, 0))) // TOP
{
raycastPlatformDir = Vector3.up;
}
else if (platformTileMap[i].HasTile(startPos + new Vector3Int(1, 0, 0))) // RIGHT
{
raycastPlatformDir = Vector3.right;
}
else if (platformTileMap[i].HasTile(startPos + new Vector3Int(-1, 0, 0))) // LEFT
{
raycastPlatformDir = Vector3.left;
}
}
raycastMoveDir = Quaternion.Euler(0, 0, 90) * raycastPlatformDir * Mathf.Sign(moveSpeed);
//raycastMoveDir = new Vector3(raycastPlatformDir.y, raycastPlatformDir.x) * Mathf.Sign(moveSpeed);
}
// Update is called once per frame
void Update()
{
MoveSpike();
}
private void MoveSpike()
{
currentCellPosition = platformGridLayout.WorldToCell(transform.position); // + raycastPlatformDir * platformGridLayout.cellSize.y / 2;
// Debug.Log(cellPosition);
//Debug.Log(raycastMoveDir);
transform.Rotate(0, 0, 300 * rotationSpeed * Time.deltaTime);
RaycastHit2D raycastMove = Physics2D.Raycast(platformGrid.GetCellCenterLocal(currentCellPosition),raycastMoveDir,0.01f,platformLayerMask);
RaycastHit2D raycastPlatform = Physics2D.Raycast(platformGrid.GetCellCenterLocal(currentCellPosition), raycastPlatformDir, platformRaycastDist, platformLayerMask);
Debug.DrawRay(transform.position, raycastMoveDir * 0.01f, Color.red);
Debug.DrawRay(transform.position, raycastPlatformDir * platformRaycastDist, Color.green);
if (currentCellPosition != startPos) { // Check on Platform corners
Debug.Log("Checking");
if (raycastMove.collider != null)
{
// reassign raycastsdirections
RotateRaycastDirections(1);
Debug.Log("Spike Collision");
}
else if (raycastPlatform.collider == null)
{
RotateRaycastDirections(-1);
Debug.Log("Spike on Platform");
}
startPos = currentCellPosition;
}
/*transform.position = Vector3.MoveTowards(transform.position,
platformGrid.GetCellCenterLocal(currentCellPosition + Vector3Int.FloorToInt(raycastPlatformDir) + Vector3Int.FloorToInt(raycastMoveDir)), moveSpeed * Time.deltaTime); */
transform.Translate(raycastMoveDir.x * Mathf.Abs(moveSpeed) * Time.deltaTime, raycastMoveDir.y * Mathf.Abs(moveSpeed) * Time.deltaTime, 0, Space.World);
}
private void RotateRaycastDirections(int angle)
{
raycastPlatformDir = Quaternion.Euler(0, 0, 90) * raycastPlatformDir * angle * Mathf.Sign(moveSpeed);
raycastMoveDir = Quaternion.Euler(0, 0, 90) * raycastMoveDir * angle * Mathf.Sign(moveSpeed);
// raycastPlatformDir = new Vector3(raycastPlatformDir.y, raycastPlatformDir.x) * angle;
//raycastMoveDir = new Vector3(raycastMoveDir.y, raycastMoveDir.x) * -angle;
}
Edit:
This doesnt work on moving Platforms though. Any ideas how i could fix that? I tried changing the raycast position to the tilemapscentercell position but it doesnt work.
public class SpawnerAI : MonoBehaviour
{
//Aha Permintaan
public GameObject[] Ahaprefab;
GameObject Ahaprefabclone1,Ahaprefabclone2,Ahaprefabclone3,Ahaprefabclone4,Ahaprefabclone5;
public Transform[] dupliposition;
//artoolkit
public GameObject ArtoolkitAc;
GameObject au,ax,artoolkitAC;
// Pergantian Permunculan AI
public Camera[] cameras;
public GameObject[] canvasall;
public GameObject[] Aishown;
public Transform[] aiposition;
GameObject peopleclone1;
GameObject peopleclone2;
GameObject peopleclone3;
GameObject peopleclone4;
GameObject peopleclone5;
private bool beingHandled = false;
public bool pos1 = false;
public bool pos2 = false;
public bool pos3 = false;
public bool pos4 = false;
public bool pos5 = false;
Animator Animdoor;
public Vector3 Gcenter;
public Vector3 TPosisi;
RaycastHit hit;
public bool touchedCh = false;
void Start()
{
cameras [0].enabled = true;
cameras [1].enabled = false;
canvasall [0].SetActive(true);
canvasall [1].SetActive(false);
Animdoor = GetComponent<Animator> ();
}
void Update () {
if (/*some case */ !beingHandled)
{
StartCoroutine (HandleIt ());
}
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit))
{
peopleclone1= hit.collider.gameObject;
Gcenter = peopleclone1.transform.position;
peopleclone2= hit.collider.gameObject;
Gcenter = peopleclone2.transform.position;
peopleclone3= hit.collider.gameObject;
Gcenter = peopleclone3.transform.position;
peopleclone4= hit.collider.gameObject;
Gcenter = peopleclone4.transform.position;
peopleclone5= hit.collider.gameObject;
Gcenter = peopleclone5.transform.position;
TPosisi = Camera.main.ScreenToWorldPoint (Input.mousePosition);
touchedCh = true;
}
}
if (Input.GetMouseButton (0)) {
if (touchedCh) {
TPosisi = Camera.main.ScreenToWorldPoint (Input.mousePosition);
cameras [0].enabled = false;
cameras [1].enabled = true;
canvasall [0].SetActive(false);
canvasall [1].SetActive(true);
//artoolkitAC.SetActive (true);
if (pos1==true) {
//pos1 = false;
Destroy(peopleclone1);
Destroy(GameObject.FindWithTag("Aha1"));
Debug.Log ("Posisi kesatu Kosong");
}
else if (pos2==true) {
//pos2 = false;
Destroy(peopleclone2);
Destroy(GameObject.FindWithTag("Aha2"));
Debug.Log ("Posisi kedua Kosong");
}
else if (pos3==true) {
//pos3 = false;
Destroy(peopleclone3);
Destroy(GameObject.FindWithTag("Aha3"));
Debug.Log ("Posisi ketiga Kosong");
}
else if (pos4==true) {
//pos4 = false;
Destroy(peopleclone4);
Destroy(GameObject.FindWithTag("Aha4"));
}
else if (pos5==true) {
//pos5 = false;
Destroy(peopleclone5);
Destroy(GameObject.FindWithTag("Aha5"));
Debug.Log ("Posisi kelima Kosong");
}
}
}
if(Input.GetMouseButtonUp(0)){
touchedCh= false;
}
//StartCoroutine(InfiniteLoop());
}
private IEnumerator HandleIt()
{
// AI
beingHandled = true;
int indAi = Random.Range (0, Aishown.Length);
// process pre-yield
Animdoor.SetInteger ("StateOP", 0);
yield return new WaitForSeconds( 3.0f );
if (pos1 == false) {
// process post-yield
yield return new WaitForSeconds( 8.0f );
Animdoor.SetInteger ("StateOP", 1);
GameObject.Find ("Bell").GetComponent<AudioSource> ().Play ();
GameObject.Find ("doorclose").GetComponent<AudioSource>().Play ();
peopleclone1 = Instantiate (Aishown [indAi], aiposition [0].position, Aishown [indAi].transform.rotation) as GameObject;
yield return new WaitForSeconds( 2.0f );
Ahaprefabclone1 = Instantiate (Ahaprefab[0], dupliposition [0].position, Quaternion.identity)as GameObject;
beingHandled = false;
pos1 = true;
Debug.Log ("Posisi Pertama telah diisi");
}
else if (pos2 == false) {
// process post-yield
yield return new WaitForSeconds( 8.0f );
Animdoor.SetInteger ("StateOP", 1);
GameObject.Find ("Bell").GetComponent<AudioSource> ().Play ();
GameObject.Find ("doorclose").GetComponent<AudioSource>().Play ();
peopleclone2 = Instantiate (Aishown [indAi], aiposition [1].position, Aishown [indAi].transform.rotation) as GameObject;
yield return new WaitForSeconds( 2.0f );
Ahaprefabclone2 = Instantiate (Ahaprefab[1], dupliposition [1].position, Quaternion.identity)as GameObject;
beingHandled = false;
pos2 = true;
Debug.Log ("Posisi Kedua telah diisi");
}
else if (pos3 == false) {
// process post-yield
yield return new WaitForSeconds( 8.0f );
Animdoor.SetInteger ("StateOP", 1);
GameObject.Find ("Bell").GetComponent<AudioSource> ().Play ();
GameObject.Find ("doorclose").GetComponent<AudioSource>().Play ();
peopleclone3 = Instantiate (Aishown [indAi], aiposition [2].position, Aishown [indAi].transform.rotation) as GameObject;
yield return new WaitForSeconds( 2.0f );
Ahaprefabclone3 = Instantiate (Ahaprefab[2], dupliposition [2].position,Quaternion.identity)as GameObject;
beingHandled = false;
pos3 = true;
Debug.Log ("Posisi Ketiga telah diisi");
}
else if (pos4 == false) {
// process post-yield
yield return new WaitForSeconds( 8.0f );
Animdoor.SetInteger ("StateOP", 1);
GameObject.Find ("Bell").GetComponent<AudioSource> ().Play ();
GameObject.Find ("doorclose").GetComponent<AudioSource>().Play ();
peopleclone4 = Instantiate (Aishown [indAi], aiposition [3].position, Aishown [indAi].transform.rotation) as GameObject;
yield return new WaitForSeconds( 2.0f );
Ahaprefabclone4 = Instantiate (Ahaprefab[3], dupliposition [3].position, Quaternion.identity)as GameObject;
beingHandled = false;
pos4 = true;
Debug.Log ("Posisi Keempat telah diisi");
}
else if (pos5 == false) {
// process post-yield
yield return new WaitForSeconds( 8.0f );
Animdoor.SetInteger ("StateOP", 1);
GameObject.Find ("Bell").GetComponent<AudioSource> ().Play ();
GameObject.Find ("doorclose").GetComponent<AudioSource>().Play ();
peopleclone5 = Instantiate (Aishown [indAi], aiposition [4].position, Aishown [indAi].transform.rotation) as GameObject;
yield return new WaitForSeconds( 2.0f );
Ahaprefabclone5 = Instantiate (Ahaprefab[4], dupliposition [4].position, Quaternion.identity)as GameObject;
beingHandled = false;
pos5 = true;
Debug.Log ("Posisi Kelima telah diisi");
}
//artoolkitAC = Instantiate (ArtoolkitAc) as GameObject;
//artoolkitAC.SetActive (false);
}
public void BacktoGameShop()
{
cameras [0].enabled = true;
cameras [1].enabled = false;
canvasall [0].SetActive(true);
canvasall [1].SetActive(false);
}
// End Of code
}
I tried many methods to destroy an instance object, but it does not get destroyed.
first I tried it with:
Destroy(ahaprefab1);
second I tried it with tag:
Destroy(GameObject.FindWithTag("Aha1"));
It still does not destroy the instance. But when i use it for Spawner Ai. Destroy(peopleclone1) does destroy the instance.
I'm stuck in this code.
well , would advice to first check if you object are not just null Debug.Log(peopleclone1)
if it's not null , try to use DestroyImmediate(peopleclone1)since the reason the gameobject is not destroy may be because he still actioning some stuff
if even DestroyImmediate don't work , then I don't realy know what to do :/
I created the sprites with images on my scene and i made work like buttons. All i want is that the all buttons are working simultaneously like multitouch screen. The code below is what i've done from now on. I use the TouchList which have gameobjects. I supposed the TouchList.Count would increase. However, the TouchList.Counts always show (number)1.
I definitely can't touch two gameObjects in same time because the state of first touched gameobject is changed to "Exit". How can i add touched gameObjects in TouchList?
Please let me know how can i fix this code.
void Update () {
if (Input.GetMouseButton(0) || Input.GetMouseButtonDown(0) || Input.GetMouseButtonUp(0)) {
touchesOld = new GameObject[touchList.Count];
touchList.CopyTo(touchesOld);
touchList.Clear();
Vector2 pos = Camera.main.ScreenToWorldPoint (Input.mousePosition);
RaycastHit2D hit1 = Physics2D.Raycast(pos, Vector2.zero);
//foreach (Touch touch in Input.touches) {
if (hit1.collider != null) {
GameObject recipient = hit1.transform.gameObject;
touchList.Add(recipient);
//Debug.Log ("recipient : " + hit1.transform.gameObject);
Debug.Log ("I'm hitting "+hit1.collider.name);
Debug.Log ("touchList.Count : " + touchList.Count);
//recipient.SendMessage("OnColliderHit",hit1.point,SendMessageOptions.DontRequireReceiver);
if (Input.GetMouseButtonDown(0)) {
recipient.SendMessage("OnTouchDown",hit1.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButtonUp(0)) {
recipient.SendMessage("OnTouchUp",hit1.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButton(0)) {
recipient.SendMessage("OnTouchStay",hit1.point,SendMessageOptions.DontRequireReceiver);
}
}
//}
foreach (GameObject g in touchesOld) {
if (!touchList.Contains(g)) {
g.SendMessage("OnTouchExit",hit1.point,SendMessageOptions.DontRequireReceiver);
}
}
}
}
This is my modified code. It works well.:-)
void Update () {
if (Input.GetMouseButton(0) || Input.GetMouseButtonDown(0) || Input.GetMouseButtonUp(0)) {
touchesOld = new GameObject[touchList.Count];
touchList.CopyTo(touchesOld);
touchList.Clear();
foreach (Touch touch in Input.touches) {
Debug.Log ("touch.position : " + touch.position.ToString());
Vector2 pos = Camera.main.ScreenToWorldPoint(touch.position);
RaycastHit2D hit1 = Physics2D.Raycast(pos, Vector2.zero);
if (hit1.collider != null) {
GameObject recipient = hit1.transform.gameObject;
touchList.Add(recipient);
//Debug.Log ("recipient : " + hit1.transform.gameObject);
Debug.Log ("I'm hitting "+hit1.collider.name);
Debug.Log ("touchList.Count : " + touchList.Count);
//recipient.SendMessage("OnColliderHit",hit1.point,SendMessageOptions.DontRequireReceiver);
if (Input.GetMouseButtonDown(0)) {
recipient.SendMessage("OnTouchDown",hit1.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButtonUp(0)) {
recipient.SendMessage("OnTouchUp",hit1.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButton(0)) {
recipient.SendMessage("OnTouchStay",hit1.point,SendMessageOptions.DontRequireReceiver);
}
}
}
foreach (GameObject g in touchesOld) {
if (!touchList.Contains(g)) {
g.SendMessage("OnTouchExit",SendMessageOptions.DontRequireReceiver);
}
}
}
}