- Home /
What is wrong with my Code? (MouseDown event doesn't work)
First of all the code:
void OnMouseDown()
{
if (clicked.Count < 2)
{
gameObject.renderer.enabled = false;
clicked.Add(gameObject);
if (clicked.Count == 2)
{
if (clicked[0].name == clicked[1].name)
{
Destroy(clicked[0]);
Destroy(clicked[1]);
clicked.Clear();
}
}
}
}
the point is i have a sphere with extern objects (pokemon figures) as childrin in the sphere and if you click on the sphere it should disappear. if you have clicked on two spheres the two clicked spheres should be compared and if they have the same figure in it both should be deleted
for better understanding it's a memory game^^
but the problem is the mousedown event don't work if i set a text in the first line everything else doesn't work i don't know why...
Where is clicked declared? Is is static or something else? If you have an instance of clicked for each object, this code will not work. You also have the problem that you are not turning off the collider, so two clicks on the same game object will count as a pair.
eeeehm... really i'm new in the using of engines this is my complete code: http://pastebin.com/NvWEWXFL
maybe you can correkt it sigh
if you mean this: the script is a component of every sphere in the scene... 54 if i'm counting right :)
There are much simpler ways of doing much of what you are doing, but on a quick read I don't see anything overtly wrong with most of the code. I don't have time to give you much feedback right now, but, if someone else doesn't answer your question, I'll take a deeper look this evening.
But, there is one fundamental thing wrong: On$$anonymous$$ouseDown() only returns true for the script the object is attached to. So in order for this script to work, it would have to be attached to every sphere. But then it would execute the global initialization code once for every sphere. $$anonymous$$ore importantly, then each sphere would get is own copy of clicked, so you'd never get two items in the list unless you clicked on the same sphere twice.
The best fix is to use Raycasting ins$$anonymous$$d of of On$$anonymous$$ouseDown() and to detect clicks on spheres. There are numerous examples of raycasting on this list. With that solution, you'd move this script to an empty game object.
I've haven't got time to take the look, but you might be able to work around this problem if you made 'clicked' static (put the word 'static' in front of the var in the declaration).
what list? raycasting? tell me more about it please _ i'm really confused i'm totaly confused i don't know what to do and this is the last thing to do in my game ^^
Answer by robertbu · Mar 11, 2013 at 02:37 AM
"okay this is a little bit much for recognizing a mousedown event"
Yes, it really is this difficult. Imagine you are standing at a window. The mountains in the distance span miles, but you might only see 30' close to the window. With Unity you are looking into a 3D environment, so the way to find things is to cast a ray. Here is an example script you can attach to an empty game object. Put in a scene with some other game objects and click on things:
using UnityEngine;
using System.Collections;
public class RaycastExample : MonoBehaviour {
void Update () {
if (Input.GetMouseButtonDown (0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Debug.Log ("Name = " + hit.collider.name);
Debug.Log ("Tag = " + hit.collider.tag);
Debug.Log ("Hit Point = " + hit.point);
Debug.Log ("Normal = " + hit.normal);
Debug.Log ("Object position = " + hit.collider.gameObject.transform.position);
Rigidbody rb = hit.collider.rigidbody;
if (rb != null)
Debug.Log ("Velocity = " + rb.velocity);
Debug.Log ("--------------");
}
}
}
}
Now here is a bit of rewriting of your code. Since I don't have your environment to test it on, there are likely issues. Since you seem to understand programming I made some changes that were not related to the immediate problem but might give you some ideas about C# and unity. Comments:
You can add a "using System.Collections.Generic;" at the top of your file and then not have to specify the full class hierarchy for the generic lists.
Unity as a build-in Random class that is seeded by Unity. No need to create an instance of System.Random.
Typically I only use the List class to store information if I don't know how many items I need to store. I would have used the built-in array class for all this code. I just converted the PokeNames array to a build-in array.
You will need to tag your spheres with "Sphere" for this code to work. You can read more about tags here.
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class NewBehaviourScript1 : MonoBehaviour { List<GameObject> SphereList; List<GameObject> Pokemon; List<GameObject> clicked = new System.Collections.Generic.List<GameObject>(); List<int> index; string[] PokeNames = new string[] {"Bisaflor","Bisasam","Celebi", "Chelast", "Chelterra", "Darkrai", "Flemmli", "Floink", "Glumanda", "Glurak", "Groudon", "Hydropi", "Impergator", "Impoleon", "Jirachi", "Karnimani", "Lohgock", "Mew", "Panferno", "Panflam", "Pikachu", "Plinfa", "Pliprin", "Schiggy", "Suicune", "Turtok", "Zekrom" }; TextMesh t; void Start() { SphereList = new System.Collections.Generic.List<GameObject>(); Pokemon = new System.Collections.Generic.List<GameObject>(); index = new System.Collections.Generic.List<int>(); GameObject[] sphere = FindObjectsOfType(typeof(GameObject)) as GameObject[]; for (int i = 0; i < sphere.Length; i++) { if (sphere[i].name == "Sphere") { SphereList.Add(sphere[i]); } } for (int i = 0; i < 27; i++) { Pokemon.Add(GameObject.Find("/"+PokeNames[i])); } for (int i = 0; i < 27; i++) { index.Add(i); index.Add(i); } for (int i = SphereList.Count - 1; i >= 0; i--) { int value = Random.Range(0, i + 1); SphereList[i].name = index[value].ToString(); index.RemoveAt(value); } for (int i = 0; i < 27; i++) { for (int j = 0; j < 54; j++) { if(SphereList[j].name==i.ToString()) Pokemon[i].transform.parent = SphereList[j].transform; } if(Pokemon[i].name=="Darkrai") Pokemon[i].transform.position = new Vector3(Pokemon[i].transform.parent.transform.position.x, Pokemon[i].transform.parent.transform.position.y - 14.0f, 0.0f); else if (Pokemon[i].name == "Flemmli") Pokemon[i].transform.position = new Vector3(Pokemon[i].transform.parent.transform.position.x, Pokemon[i].transform.parent.transform.position.y - 8.0f, 0.0f); else if (Pokemon[i].name == "Mew") Pokemon[i].transform.position = new Vector3(Pokemon[i].transform.parent.transform.position.x, Pokemon[i].transform.parent.transform.position.y - 26.0f, 0.0f); else if (Pokemon[i].name == "Chelast") Pokemon[i].transform.position = new Vector3(Pokemon[i].transform.parent.transform.position.x, Pokemon[i].transform.parent.transform.position.y - 8.0f, 0.0f); else Pokemon[i].transform.position = new Vector3(Pokemon[i].transform.parent.transform.position.x, Pokemon[i].transform.parent.transform.position.y - 7.0f, 0.0f); } } void Update() { if (Input.GetMouseButtonDown (0)) { RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); if (Physics.Raycast (ray, out hit)) { if (hit.collider.tag == "Sphere") { if (clicked.Count < 2) { clicked.Add(hit.collider.gameObject); hit.collider.gameObject.renderer.enabled = false; hit.collider.enabled = false; if (clicked.Count == 2) { if (clicked[0].name == clicked[1].name) { Destroy(clicked[0]); Destroy(clicked[1]); } else { clicked[0].renderer.enabled = true; clicked[0].collider.enabled = true; clicked[1].renderer.enabled = true; clicked[1].collider.enabled = true; } clicked.Clear (); } } } } } } }
okay it seems to work now maybe i'll change it a little bit because there are a few Problems occuring (btw. i always get an error saying index is out of range do you know how this can be?) but the rest has to be my unintelligent click-code^^
by the way can you answer me another little question? maybe i need it for my next project.
i imported several objects with textures and i'm not sure but i think skelleton data is in there too ... und meshs... and what ever xD
so i think it's impossible to make my figures move... at least there IS skelleton data in a ... smd or psk file i don't remember and don't know if it's imported but yes...
the question is: how can i animate them?
Okay i'm so sorry but i need help again here the new code: http://pastebin.com/k$$anonymous$$39qGRX
i always get nullreference exceptions but... i don't know where it has some problems with line 85 and 64 so it has to be the List Pokemon or SphereList i don't know what it is...
the code should work or not? now i copied the 27 extern objects i already had and duplicated them i renamed every Pokemon name so that it has a 2 at the end and added them to the list... now i want to match them to the other spheres with the same index (you know i got 2 named 1 2 named 2 etc)
then i excluded the already matched spheres with putting their index in another list and used the Contains function for the other for-routine..
it should work ... please help me i don't know what to do ... god i hate unity
I don't see a problem if I just look at the code. With this kind of problem, it is easiest to sort it out if you 1) post the exact error message(s), and 2) you comment the actual line(s) where the error occurs since the line numbers in codes pasted above and/or pastebin do not align with the number in the error report.
As a step to figure out your problem, write code to verify your data structures. As a start verify that all of the game objects in the Pokemon list are not null. Print out all the names to make sure that you have exactly what you expect on the list. Note that any mistake in na$$anonymous$$g will cause your code to fail.
i tried it but i don't get it really i tried to check the number of elements in all lists i tried to use arrays ins$$anonymous$$d the code is just wrong... maybe it helps if i send you the complete projekt?
the answering structure here is were complicated xD sorry for reposting
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
How to make a custom cursor, and have that cursor rotate towards a gameObject such as the player? 1 Answer
Distribute terrain in zones 3 Answers
Remove a known TreeInstance at runtime. 0 Answers
GetComponent C# 1 Answer