"Attaching" instantiated prefab to a gameobject - unity3d

I have 2 game objects (2D project):
GameObject enemy1 = GameObject.Find("Enemy1"); // Sprite Renderer "Order in Layer" 1
GameObject enemy2 = GameObject.Find("Enemy2"); // Sprite Renderer "Order in Layer" 2
A fire prefab is instantiated (just a fire animation):
GameObject go = Instantiate(Resources.Load<GameObject>("Animations/Fire1")); // Sprite Renderer "Order in Layer" 5
go.transform.SetParent(enemy1.transform);
go.transform.position = enemy1.transform.position;
Since the fire prefab's Sprite Renderer's Order in Layer is 5, it always on top of both enemies.
I would like the fire to appear above enemy1 but behind enemy2 regardless of what their Order in Layer is changed to. Basically, it should look like the enemy is catching fire, even if it moves or if it's layer order changes.
How can this be achieved? I thought making the fire prefab a child of the enemy gameobject would do it, but it doesn't.
Edit:
Making the fire animation a child of the enemy manually in the editor works perfectly. How do I replicate that with code?

Instantiating the prefab in this way fixed the issue:
go = Instantiate(Resources.Load<GameObject>("Animations/Fire1"), enemy1.transform);
Changing the added prefab's sortingOrder was also necessary to make things working correctly:
go.GetComponent<SpriteRenderer>().sortingOrder = enemy1.GetComponent<SpriteRenderer>().sortingOrder;
After this there was a small issue - the instantiated prefab would randomly appear behind or in front of the enemy. This was fixed by adding a Sorting Group component to the fire prefab.

Related

Character falling through floor unity

I had this working just fine until I decided I wanted to change how I organized the colliders just a few minutes ago to avoid having multiple colliders on the same object.
I have a "Player" object with a boxCollider2d with isTrigger=false and an empty child called "triggers" which itself has 2 children, each with a single boxCollider2d and both with isTrigger=true. These triggers are used for detecting when the player is grounded or next to a wall but are not supposed to affect the physics.
I also have a "floor" object which has a sprite and an empty child called "colliders" which has a single child called "ground" with a single boxCollider2d (isTrigger=false) and the layer of the object set to "Ground".
My understanding is that since my player has a non-trigger collider (and rigidbody) and the floor has a non-trigger collider (at least its child does), that the character shouldn't pass through the floor. Also, it's starting from a height above the ground so it's not an intersection problem.
My best guess is that somehow the child colliders of the player being triggers are turning the main collider into a trigger or that for some reason the floor collider being in a child is screwing with it, but I don't know enough about how these colliders work to really know.
The child trigger colliders should not cause it to mess up like that.
Check Project Settings -> Physics 2D -> Layer Collision Matrix. Are your objects not able to collide?

Trail renderer does not behave correctly

I have had this issue for a while and I can not find a solution to fix it. I manage to shoot bullets with trails. To do this, I create a bullet prefab and add a trail renderer to it. I shoot the bullet in another soldier game object by following steps:
Load the bullet prefab:
private void Awake()
{
bulletPrefab = Resources.Load<GameObject>("Enemy/Bullet");
Instantiate bullets from bullet prefab:
private void shoot(){
bullet = Instantiate(bulletPrefab);
bullet.transform.position = this.transform.position;
...
}
Then I update the bullet position according to the calculated angle and bullet speed. The problem is that when I shoot a bullet, the bullet will cast two trails, one trail going toward to the target which I set in the script and the other point to the bullet prefab I load in the Awake function. It seems that the bullet prefab loaded from resource folder does not show in the scene. However it affects the bullets which instantiated from it, making them point a trail to it.
How can I fix this issue?
I have resolved this issue by myself. The cause of this issue is actually pretty simple. I should choose Instantiate(Object original, Vector3 position, Quaternion rotation) rather than Instantiate(Object original).
The first version of instantiate creates the bullet in the given position; relocating the prefab after using the second version will render the unwanted trail.
You can also use the TrailRenderer.emitting option.
just set the emitting to false in by default and right before firing change it to true using myTrail.emitting = true;

Two collider in one game object how to distinguish between them when colliding with another?

I'm making a 2D game, there is one player with two collider : a box collider 2D on top and a small circle collider 2D bottom. When the player jump on the box he will be ok, but when he collide with the box with his face(box collider 2D) he will die ? How can I do that? I tried the following code , but it not work. Please help me.Thanks!
if (GetComponent<Collider2D>().GetType() == typeof(BoxCollider2D))
{
//do something
}
if (GetComponent<Collider2D>().GetType() == typeof(CircleCollider2D))
{
//do something
}
If you want to get a certain BoxCollider, you can use GetComponent<BoxCollider2D>() and GetComponent<CircleCollider2D>()
However, I am not sure how to take this information and check which one fired the the OnCollisionEnter, unless you set one collider to a trigger, and use OnTriggerEnter for one, and OnCollisionEnter for the other.
What I would recommend is having two child game objects on the player and put both colliders on each game object, and handle each event in their own OnCollisonEnter

Sprite disappearing to the back of another sprite on moving to defined point via transform.position

I have a difficulty with Unity2D's Sprite rendering.
Currently I have a sprite for a gameBoard, an empty GameObject holding the spawnPoint, a random sprite marking it, as well as a playerSprite to be instantiated as a prefab. If I am just using the hierarchy on Unity, the playerSprite shows perfectly above the gameBoard, and "hard-coding" its position will always keep it above the gameBoard sprite, visible to the eye.
The problem comes when I want to instantiate the gameBoard and dynamically adding the playerPrefabs into the game.
Here is the current code snippet I am currently using:
gameBoard.SetActive(true); //gameBoard is defined as a public gameObject with its element defined in Unity as the gameBoard sprite.
Player.playerSprite = (GameObject)Instantiate(Resources.Load("playerSprite"));
Player.playerSprite.transform.localPosition = spawnPoint.transform.localPosition;
The result is that the spritePrefab spawns at the place I want perfectly, but behind the gameBoard sprite, making it hidden when the game runs.
The result is the same when using transform.position instead of transform.localPosition
How should I code the transform part. such that I can still make my playerSprite visible? Thanks.
It's most likely not an issue with the position, but rather the Sorting Order of your Sprite Renderers.
The default values for any SpriteRenderer is Layer = Default & Sorting Order = 0
Sprite Renderers with a higher sorting order are rendered on top of those with a lower value.
Add the following lines to the end of your code, and try it out.
gameBoard.GetComponent<SpriteRenderer>().sortingOrder = 0;
Player.playerSprite.GetComponent<SpriteRenderer>().sortingOrder = 0;
Obviously, you could do the same thing in the inspector as well.

SpriteKit Physics Bodies Collisions in Multiple Layers

Okay, so I'm writing code for a space blaster game, and all seems to be going well, minus these crucial issues.
First, I added a spaceship (with PhysicsBody) as a child of self (GameScene).
Then I added a background layer as a node also as a child of self, behind the spaceship, and simulated movement by moving the background around behind the spaceship via joystick control.
I added a node with a boundary physics Edge Loop body so the background wouldn't move beyond the ship, and added that node as a child of the bgLayer.
I have objects for the spaceship to shoot at, but I want them to move around as the background does, so I added them as children of the bgLayer.
Of course, I needed a laser when the spaceship fires, so I added this as well as a child of the bgLayer.
_spaceship.physicsBody = (custom physicsBody code);
[self addChild:_spaceship];
_bgLayer = [SKNode node];
[self addChild:_bgLayer];
_bounds = [SKNode node];
_bounds.physicsBody = (physicsBody edgeLoop code);
[_bgLayer addChild:_bounds];
_otherObjects.physicsBody = (custom physicsBody code);
[_bgLayer addChild:_otherObjects];
_laser.physicsBody = (custom physicsBody code);
[_bgLayer addChild:_laser];
All is well, the background doesn't move beyond the spaceship,the other objects move as the background moves, and the laser fires when called upon.
My first big dilemma is when my laser fires, it does not move as the background moves, but the background moves behind it. I could probably make do but it looks funny if the laser always moves in parallel with the ship. This seems odd to me since I added the laser as a child of _bgLayer.
Second, my laser's physicsBody doesn't seem to recognize the EdgeLoop body, and sails right on through it. Also, my spaceship's physicsBody seems to recognize the EdgeLoop body, but it does not recognize the other objects that are children of _bgLayer.
Do Physics Bodies that are not children of the same layer recognize each other?
And why doesn't my laser behave similarly to other children of the same layer?
Moving the world by changing its position will affect
Children with physics bodies
Children without physics bodies
Moving the world by applying a force/impulse or by settings its velocity will affect
Children without physics bodies
Instead of moving the world by setting its velocity, you can add a camera (an SKNode with a physics body) to the world, move the camera by setting its velocity, and then update the position of the world to center the camera. You can center the camera in the didFinishUpdate method.
-(void)fireLaser
{
_laser = [SKSpriteNode spriteNodeWithImageNamed: [NSString stringWithFormat:#"blueLaser"]];;
_laser.zRotation = _spaceShip.zRotation;
CGVector rotationVector = RadiansToVector(_spaceShip.zRotation);
_laser.position = (Custom code for positioning the laser just in front of the spaceship);
_laser.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_laser.size];
[_bgLayer addChild:_laser];
_laser.physicsBody.velocity = CGVectorMake(rotationVector.dx * LASER_SPEED, rotationVector.dy * LASER_SPEED);
}
[self fireLaser] is called in touchesBegan when a particular SpriteNode is touched.
The laser fires beautifully, but does not scroll with the background, but rather moves in relation to the spaceship. Background scrolls with a PhysicsBody and a setVelocity method is called when the joystick moves, thus simulating spaceship motion, when in reality the spaceship never leaves the center of the screen. Physics categories prevent the background physics body from colliding with anything. LASER_SPEED is simply a static const float.