Instantiating object with physics on Canvas - unity3d

I've been trying to instantiate simple object on my canvas that would show added score value with some small visual and then fall down with gravity for a while before disappearing.
I Cant in any way make it visible as UI element.
It is spawning at ridicolous position where canvas objects are physically. and even if i instantiate it as a child of my Ui element it has RectTransform but is not visible by camera as Ui element.
in my script "scoreValue" is ui element under which i'd want it to be instantiated,scoreVisualisationSpawnPoint is normal object with trasnform position i used earlier.
How to instantiate object on canvas at certain position in canvas for it to be visible?
Here is my not-working code:
public void CreateAddScoreVisualisation(int addedScore)
{
GameObject effect;
effect = Instantiate(addScoreVisialisation, scoreVisualisationSpawnPoint, scoreValue.transform.rotation,scoreValue.transform);
effect.GetComponent<RectTransform>().position = scoreValue.rectTransform.position;
effect.GetComponent<ScoreVisualisation>().scoreText.text = addedScore.ToString();
}

That can be tricky at times, but are you sure this is the right approach at all?
I'd suggest have your object permanently there so you can set it up as you wish with the inspector and then in the start function, call gameObject.SetActive(false) to disable it.
Then instead of instantiating, activate it.
This will also be more performant by the way because small, inactive objects don't cost much but instantiating and destroying is relatively expensive.

Related

Using one scene for infinite levels

I am trying to make a game where there is a single scene, which will be used for an infinite number of levels until the player loses. All of my code is currently in a GameController script, and I have it so that when the level is completed, the player will press a key and integer for the level will be incremented, and the same scene will be loaded.
void Start()
{
gamePlaying = false;
currLevel = 0;
BeginGame();
}
void Update()
{
if (Input.GetKeyUp(KeyCode.Return))
{
currLevel++;
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
I have this script and a DontDestroyOnLoad script attached to the GameController gameObject.
This currLevel variable is staying at 0 when printing to the console; however, it is updating in the inspector. What am I doing incorrectly, and is this a good way of setting up this project? Thank you!
There are some ways to implement this but I would recommend to not reload the scene but have a list or container with the objects you want to destroy and when loading the next scene you destroy these and create new. You can easly make a loading screen in this time and even better pre buffer the new scene when you notice the old one is comming to an end.
So instead of reloading the scene, destroy unnecessary objects and create the onse you need. Depending on your needs you may even reuse some as the floor for example and just change the color for your level. As said that all depents on your usecase.

Why does parenting an object in the hierarchy produce different results then parenting via script?

Parenting GIF (for visual)
When parenting an object using the hierarchy you click and drag that object and place it into another game object.
When parenting an object using a script, it looks something like this
myObject.transform.SetParent(parentObject, false);
Now, if you watch the GIF you will see that the two different methods of parenting produce different results for the child objects transform values. The resulting position and scale are different for the child object depending on which approach to object parenting is used.
How do you get the same results produced when parenting in the hierarchy via click and drag, when parenting by script?
EDIT: Forgot to add that when watching the gif, you can see the click and drag parenting first and watch the transform values change. I then control Z to undo the change, click into the scene view, and execute a button press that sets the parent of the 'blue' game object to 'myObject'. Note, you will see the transform values don't change when parenting is done via the latter method.
If we check Unity's API documentation for the SetParent() method we can better understand how this method works. In my case I was using the method that used two parameters:
parent:
The parent Transform to use
worldPositionStays:
When false the object keeps its local orientation rather than its global
For my question, there are two simple solutions:
Set the worldPositionStays parameter to true so that the parent-relative position, scale and rotation are modified such that the child object keeps the same world space position, rotation and scale as before, or
Use the SetParent() method with only the parent parameter, effectively yields the exact same result as setting worldPositionStays to true.

GameObject isn't in the hieararchy, but its script's Update is called?

Now I am facing a ghost object.
There was a script attached to an object which I deleted. But for some reason, the script's update function is always being called.
I added this line to the Update: Debug.Log(name), and its name is Flamestrike, but when I search it in the hierarchy, there are no results.
And if I set its position to 0,1,0 (so it should be visible), it is not visible in the game either.
So please help me because it drives me crazy :(
Edit:
Debug.Log("a");
if(transform.parent == null) {
transform.SetParent(GameObject.Find("Canvas").transform);
Debug.Log("Canvas");
}
I also tried this, and it prints Canvas, so it sets its parent to Canvas, but I can't see any Flamestrike objects under Canvas.
When Instantiating a prefab GameObject, for some reason it was being created with Hidden Flags. In order to solve this, we added the code: this.gameObject.hideFlag = HideFlags.None; which allowed the object to show up in the hiearchy finally.
The only other source I could find on this was this answer, which had basically no explanation as to why it occured. http://answers.unity3d.com/questions/921819/instantiated-prefabs-not-showing-up-in-hierarchy.html (quoted below)
Found the issue, not sure why but: These two ways are working (prefab
is a GameObject defined elsewhere).
Player1 = Instantiate(prefab) as GameObject;
Instantiate(prefab) as GameObject;
For some reason the prototype:
Instantiate(prefabName, position, rotation);
Was not working.
(Sorry if this is not the correct way to write this, but the comments are too short, and can't be formatted)
This not fully true, I think.
This hidden gameObject wasn't created via script. I dragged the prefab to the scene, then somehow I didn't delete the prefab fully. (or didn't even delete, just made it hidden)
It disappeared in the hieararchy, but it wasn't deleted fully.
After we made the object visible via script, now it is visible.
(but only in play mode, so I can't delete it, because it is not visible in scene view)
And it got some interesting components/attributes.
The original story:
FlameStrike - a Container for scaling purposes (empty gameObject)
-FlameStrike - a gameobject with animation, FlameStrike.cs script etc.
--Particle System - a part. system with this exact name.
But after we found the remaining hidden object it was like this:
So I don't understand what I did. It deleted some parts of the prefab, but also mixed some parts,
(like adding the Particle System object's Particle System component to this FlameStrike object)
then made it hidden. Is there a hotkey for this? :D Because it is not script related issue, I did this in the editor.

SWIFT: SKSpriteNode setting alpha to 0 vs. removing it from it's parent

I have a problem and I have to admit, I'm a bit of confused. I have to show/hide some SpriteNodes (those are some option buttons that will appear if the game is over). If the retry "button" (SpriteNode) is pressed by the player, the method that is called by that touch is setting it's alpha to zero. But sometimes it remains "active"(means alpha remains 1), behind other sprites and while the game is played again and the nodes that are in front of it are moving and it becomes visible. That is very confusing and being a random behavior I was thinking if removing it from it's parent (which is self, anyway) and adding it again when it's necessary is a better way to approach that kind of situations.
The code is like:
func restartGame()
{
restartButon.alpha = 0
......................
}
if nodeAtPoint(location).name == "someName"
{
restartGame()
}
It's good to mention that the appearance of this button is made by SKAction.fadeAlphaTo(1,1.5) and it's initially alpha is set to 0 in didMoveToView() override method.
Thanks.
If you still seeing it, it obviously means something in your program is setting the alpha to 1.
Why not just set the node's hidden property to true? This will hide it.
In general, if this is for UI elements which are not always displayed, you are better off by controlling these pieces by a parent node which can contain all of the UI elements. For example, you could have a "menu" node, which contains all of the button nodes. Note this is very simplistic in that more complicated UIs would require a more complicated node hierarchy. But this would work if your UI is layer "floating" over the game.
The advantage of this is you could either remove everything by removing the parent from the tree or just set the parent's hidden property to true

Creating pointer Attributes in cocos2d iPhone

I am working on a game. There are balls that fall from the top of the screen, and the player has to catch them, as the are caught they stack ontop of one another. I have a method that creates each new ball and adds it to an Array that i use to move the sprites. Problem is that the after they collide I need them to stop moving, since the array is called on to move them they all move. And if i try to make them stop they all stop. So I was hoping to create a pointer attribute if ther is such a think, for example "sprite.position" I need a new attribute that i can check like a boolean. I was hoping to create a attribute like sprite.hasCollided and if it returns YES then the ball should no longer move. Is this possible or is there a better way to do it?
Thanks
Tanner
I would suggest you create a ball object. And add the boolean as as part of the object.
CCNodes (and, by inheritence, CCSprites) have a userData property, which is a void*. You can use this to relate a custom object to a cocos2d object. Keep in mind if you use the userData option, you will, in most cases, need to allocate any memory when you create/assign the sprite, and release it when you are done.
int* myInt = (int*)malloc(sizeof(int));
*myInt = 0;
sprite.userData = myInt;
//some time later, when you are done with the sprite
free(sprite.userData);
As an improvement on the userData property, you can do what xuanweng suggests and create a ball object containing various game-related properties for the balls, and assign an instance of this to each of your ball CCSprites using the method above.