Unity parenting and deparenting game objects - c#

I'm currently implementing a wall climbing system into my 2D game and I'm stuck on a few of the trickier parts.
My thinking is that I would have my player parent to the wall object when it collides with the 2D collider attached. When the player collides with the wall, the player becomes a child of that wall and is limited to only moving up and down on the wall. When the player jumps, or reaches the top, they are no longer a child of the wall. But the player has the ability to jump on any point onto the wall they land on and stays at that point.
Right now I have the parenting part worked out with the following code (this code is attached to the player):
void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.tag == "Wall")
{
this.transform.parent = collision.transform;
Debug.Log("hit a wall");
}
}
The two areas I'm struggling with are de parenting my player from the wall and having the player still to the position on the wall where they land.
With the first part (de-parenting) I believe I'll need to make use of the following code:
void OnCollisionExit2D(Collision2D collision)
{
if(collision.gameObject.tag == null)
{
this.transform.parent = null;
Debug.Log("not hitting anythin");
}
}
However, when I run this, my player doesn't deparent right away. Am I doing it correctly?
I'm also clueless as to how to begin my other problem of having the player stick to the part of the wall they connect with. Can someone please help me with my issues?

Ideally you'd use tranform.SetParent for the extra you get over position.
transform.SetParent(parentTransform, true);
transform.SetParent(null, true);
if the latter line is fired it should detach from it's parent to the best of my understanding and the 2nd parameter on SetParent should fix positioning issues.
Though your existing code should at least change the hierarchy, I suspect the issue there is your collision code - if you enter a collision with Tag:Wall then you're going to exit a collision with Tag:Wall not Tag:Null.
However #limoragni is right, editing your hierarchy is going to have no effect on the possible movement of your character unless you've specifically coded that in yourself. You could just as easily set a boolean and use your code with that.
Ref:
http://docs.unity3d.com/ScriptReference/Transform.SetParent.html

Related

How do i make my player move with a moving platform in unity 2d

I'm making a 2D platformer and decided to add sticky platforms. I've made the platforms move, but the player doesn't move with them.
However, after parenting the player to the platform, the player still falls through. I have added two BoxCollider2Ds and set one of them as a Trigger. None of the colliders have a RigidBody2D
public class StickyPlatform : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.name == "Player")
collision.gameObject.transform.SetParent(transform);
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.name == "Player")
collision.gameObject.transform.SetParent(null);
}
}
trigger does not stop object move through the box, you can try OnCollisionEnter.
Usually I would have a ground check and you can say if(isGrounded&&onPlatform) //move with platform
So it sounds you have two problems:
Player is falling through platform
Player isn't sticking to the platform
Falling through the floor is a super common bug, with many causes. Here is a checklist I found:
does Object have a Collider? If not, select Object
go to the top bar
components
physics
choose appropriate collider
(if Terrain, check the last tab, the little cog-wheel)
Note: mesh-collider may cause problems
Particularly, if both FallingObject and GroundObject have mesh-collider
Particularly, if the mesh is animated
To avoid mesh-collider, you can build an aproximate shape of your mesh from
several primitive colliders (in parent-, child- or sibling-GameObjects)
If you need a Mesh-collider no matter what, you can try to place additional primitive colliders where they won't be in the way to 'enforce' the collisions
Is the Object a Trigger? If so, select Object
find its Collider-Component (if Terrain, check the last tab, the little cog-wheel)
remove the check of 'IsTrigger'
Is the Collider placed well?
Fiddle with center, size and skin-width (start with 0.1) until the green outline aproximately fits the character
(If you get really strange values, it might be due to scale (e.g. your mesh was way too big so you downsized to .01))
You may try to zero out all positioning (both unity and your modeling-program)
The link goes into even more cases.
Once the player can stay on, the physics engine should handle the momentum transfer to move the player with the platform using friction. Which again, requires RigidBody2D. I'm not sure why you're not using RigidBodys, it kind of feels like you're avoiding the solution.
Doing it this way should avoid the need to parent the player, and have a trigger volume as well, unless you want the player physically stuck and can't move on the platform.

Unity 3d collision detection

I've been tearing my hair out for weeks just trying to detect a collision between a RigidBody and a BoxCollider tied to a spot light that is tied to the camera, I want to detect when the player is flashing their flashlight at something, but for some reason this doesn't work.
I don't think it's detecting the collision at all, the variable "test" does not change and nothing appears in console, the flashlight hitbox I'm sure is large enough, but the console still gives no indication of anything happening, I was following this tutorial: https://www.youtube.com/watch?v=QRp4V1JTZnM
and here's the simple code I made:
void OnCollisionEnter(Collision col) {
if (col.gameObject.name == "Spot_Light") {
Debug.Log("detected");
test = 375;
}
}
If you marked trigger in your collider, you cannot use the OnCollisonEnter to detect a collison, you should use the OnTriggerEnter instead.

Child position is moving along with parent, but not actually moving (moving platform)

So I have been stuck on this for the last few days, researched and tried a lot of things but still can't figure this out.
I have a player with a Rigidbody and a moving platform with a Rigidbody as well. The platform is moving back and forth and I want the player to stay on it when he's on.
So when the player jumps on the platform, the platform become it's parent. This is working fine, no problem on that end.
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Moving Platform"))
{
transform.parent = collision.gameObject.transform;
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Moving Platform"))
{
transform.parent = null;
}
}
The thing is, since the player has a Dynamic RigidBody, it looks like the movement of it's parent does not affect him. I can see his position moving in the inspector, but it's not really moving in the game.
When I set the body type to kinematic, the player stays on the platform but then I can't find a way to actually move while on it. So he gets basically stuck on the platform.
Is there an easy fix for this ? Or should I completely change the way I am making these moving platforms.
(BTW, every movements are handled with physics)
When you move the player sometimes it detach from collision even with small margin and will give weird results. try Physics2d.OverlapCircle instead.

Why is my bullet moving through my enemy and not detecting a collision?

I have my Unity 2D project set up so that the bullet is a trigger and will detect and collisions but not interact with the environment, and my enemy being a collider so that it will do both. I don't know if the fact that they are two different types affects collisions, but I thought I'd include that detail incase it did. I know this issue is not caused by my bullet moving too quickly since when I turn the speed of the bullet down the issue persists. I will include the code for the enemy collision and the bullet collision detection here:
void OnCollisionEnter2D (Collision2D coll)
{
if (coll.gameObject.tag == "Proj") {
Destroy(gameObject);
Debug.Log("Hit");
}
Now for the bullet:
void OnTriggerEnter2D(Collider2D hitInfo)
{
if (hitInfo.gameObject.tag == "Enemy") {
Destroy(gameObject);
}
The bullet is detecting a collision with an enemy and deleting itself, but the enemy is not detecting a collision with the bullet and taking damage/deleting itself. Even when I turn off the Destroy(gameObject) part of the bullet code so that it doesn't destroy itself on collision I still have the same problem so I know it isn't matter of it deleting before anything detects. I hope I was thorough enough with my explanation and that someone can help me resolve this issue.
Image of the inspectors: https://imgur.com/a/TLfcNcp
The bullet needs to be a non-trigger collider as you are calling OnCollisionEnter and not OnTriggerEnter from the enemy script.
Please show the settings of each collider, also OnCollisionEnter2D and OnTriggerEnter2D are 2 different things, and will occur in different conditions, so make sure that you are using the right one for the player.
I'm not entirely familiar with trigger behaviour, as it's been a while since I've played around with those, but this bit of documentation for MonoBehaviour.OnTriggerEnter2D(Collider2D) is an important starting point for solving your problem:
Trigger events are only sent if one of the Colliders also has a Rigidbody2D attached.
I can't say for sure, but your screenshots suggest that there is no Rigidbody2D involved.
Interestingly,
documentation for Collider2D.OnTriggerEnter2D(Collider2D) neglects to specify that a Rigidbody2D is necessary. I'm not sure what this implies; both MonoBehaviour.OnTriggerEnter(Collider) and Collider.OnTriggerEnter(Collider) (the 3D analogues) are said to require a RigidBody. Both of these pages also claim
If both GameObjects have Collider.isTrigger enabled, no collision happens.
However, the example code from Monobehaviour.OnTriggerEnter2D(Collider2D) claims that setting both 2D colliders as triggers will still allow the function to be called.

Networked AR Unity can't make a bullet a child of the ground plane stage

I am trying to make an AR game and am currently using Unity's high-level networking classes. I have set my player prefab to be spawned in one of the two network spawn locations, which are both childs of the Ground Plane Stage. When user has tapped to make their ground plane stage and has tapped to be the host, their player character appears. Unfortunately, if they press the fire button, the bullets appear above the stage and unscaled, meaning they aren't parented to the stage. This confuses me because I've checked many times and the bullet emitter is a child of the player, and in my code it references said emitter. Thus I'm rather confused why the bullets don't seem parented.
I've attempted to attach a script to make the bullet emitter a child of the player when it spawns. I've also tried making it a child of the stage when it spawns. I've tried making the player character not dependent on the Network manager spawning it when the player joins, but then that leads to other networking problems when it comes to controlling the character, but it can shoot then.
The only one that was relatively successful was making the bullet a child of the stage when it spawned, but it would only stay in one place. Attempting to make the bullet a child of the player did nothing
//This is the class I'm trying to use to make the object a child of
something
public class AddToBeetle : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject player =
GameObject.FindGameObjectWithTag("Player");
transform.SetParent(beetle.transform, false);
}
}
It rarely prints any error messages. I hope that I can eventually get the bullet to spawn in front of the player model when the button is pressed.
Oh gosh I was dumb, the one thing I didn't apply the script to was the player's bullet emitter. It was super late and that's probably why I missed trying it on that. Anyway I hope this helps someone else if they ever have to deal with AR and Unity.

Categories