I'm working on a 2D platformer game in Unity. My character moves by applying velocity to the rigid body and works just as I want it to for precise controls.
When the character is on a moving platform, I parent the character to the moving platform so that the character stays on while the platform moves. Here's the code that's on the moving platform
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Player")
{
collision.collider.transform.SetParent(transform);
}
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.tag == "Player")
{
collision.collider.transform.SetParent(null);
}
}
I'm also using transform.position from one position to another to move the platform.
Here's the issue. The character works perfectly fine only if the speed of the platform is 0. If the platform is moving at all, the character will move like a slug while walking on the platform. Any ideas on how to fix the issue or is there a way to have the character ride on the moving platform without parenting it to it?
Edit: I forgot to include this earlier. I've tested to see if the physics materials would make a difference. I included a 0 friction physics material on the character, the platform, and both at the same time. None of the combinations made any difference. The player still move sluggish while the platform is moving.
If you are moving your character with a force and a rigidbody, the hierarchy and who is the parent is not going to have much influence as the movement is provided by the force, this is with the physics.
If you where manipulating the transform in the code for the movement that would be important, but if movement is produced by forces I think its not.
I would check the frictions of the Physic Materials of the player and the platform in order to define the movement of the elements respect each other.
It is quite a while for the answer but I think I found one. Moving the platform in FixedUpdate rather than in Update can fix this issue.
Related
I have a ball in my demo game that has a bounce rate of 0.6. If the ball lands on a platform, of course it bounces. But the thing is, I actually tried to stick the ball to the platform.
When the ball collides with the surface of the platform, the speed of rigid body 2D becomes 0. But I guess because of the bounce rate, ball jumps a little bit and lands again in 0.02 seconds. Because of this, OnCollisionEnter2D runs for 2 times, which is something I don't want. Here is my code;
private void OnCollisionEnter2D(GameObject other) {
if(other.GameObject.tag == "platform") {
//Sets the rigidbody2D velocity as zero vector, angular drag and linear drag as 10f
game.SetBallVelocity(Vector2.zero, 10f, 10f)
}
}
How can I make OncollisionEnter2D only runs for single time? In another word, let the Ball really stick at the first time?
I don't have enough information to give you the exact answer but one of those should fix the problem:
1: Changing collision mode on the ball's rigidbody (test both Discrete and Continuous)
2: OnCollisionEnter2D is called before the physics calculations that change the ball's velocity, so use OnCollisionExit2D()
Quick side note, your IDE should have warned you of this but other.gameobject.CompareTag("platform") is faster than directly comparing the strings (other.GameObject.tag == "platform")
I'm developing a simple 2D Unity game (which I'm very new to so sorry if this is a silly question!) in which my player can eat its enemies by colliding with them. This works fine as I'm just selecting the "is trigger" component for the enemies and using this code in my Player class:
private void OnTriggerEnter2D(Collider2D other)
{
Debug.Log("Hit detected");
Destroy(other.gameObject);
transform.localScale += new Vector3(x, y, z);
}
However, this means the colliders placed around the border of my background image aren't stopping the enemies. What's the best fix for this?
I don't understand very well your question. However it seems that your collisions are not working. So, remember that for have collisions actually taking place in your game you need to use colliders and that one of the two elements participating in the collision need to have the rigidbody component.
That will make the physics work in the engine, which triggers dont.
To check if that works you can debug with:
// called on collision
void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("OnCollisionEnter2D");
}
From what I understood, you want only to detect triggers between the player and the enemies, but you still want these to collide with physic objects in your scene, such as background colliders.
One possible way to achieve this is to create a child object for the player object with a collider component with the trigger option set, and attaching a script to it to handle the triggers. Then, with the use of layers to group your player and enemy objects, you can uncheck the collision between them following: Edit -> Project Settings -> Physics 2D: "Layer Collision Matrix".
You can assign a script to any enemy, checking the distance with the player in each frame. Then you can Uncheck "is trigger"
Vector2.Distance
I made a moving platform that goes vertically top to bottom and then bottom to top and so on. Platform moves fine but placing my player on it makes my player unstable.
When platform moves from top to bottom, my player kinda bounces on it. When platform moves from bottom to top, it remain stable on the way but when it reaches top point, my player makes a jump by itself.
Its get even worse when i increase the speed of my platform. I don't know if its due to unity 2d physics effect or what. I have tried to use physics material 2D on my player object and platform by setting bounce to 0 and friction to 50 but nothing seems to work. Any one have idea how to disable physics effect of moving platform? Following is my code for moving platform:
public class BrickMoveVErtical : MonoBehaviour {
public Vector3 positionOne;
public Vector3 positiontwo;
public Vector3 nextposition;
/*Empty object is already made on unity editor and its parent of platform(Plank) and other
empty object "pointB". Point "B" is already mapped on editor and platform is set to go from
its original pos to point B */
public Transform plankTranform;
public Transform positionBTransform;
public float speed;
// Use this for initialization
void Start () {
positionOne = plankTranform.localPosition;
positiontwo = positionBTransform.localPosition;
nextposition = positiontwo;
}
// Update is called once per frame
void Update () {
move();
}
private void move() {
plankTranform.localPosition = Vector3.MoveTowards(plankTranform.localPosition,nextposition,Time.deltaTime*speed);
if(Vector3.Distance(plankTranform.localPosition,nextposition)<0.1)
{ changeMovementPlank(); }
}
void changeMovementPlank() {
nextposition = nextposition != positionOne ? positionOne : positiontwo;
}
}
I had similar problems with fast platforms in my game, the character would be left out in the air or slide off, depending on the direction of the platform.
I found a workaround for the problem by simply changing the character transform.parent to the platform it was jumping on, whenever the player exists the platform collider, simply return the players original transform.parent.
Note that this might cause other bugs or problems that will need to optimize, depending on your game that is.
You can use this code to set/unset the parent of a GameObject:
void OnTriggerEnter2D(Collider2D other)
{
if(other.gameObject.tag == "PlatformGroup")
player.SetParent(other.gameObject.transform)
}
void OnTriggerExit2D(Collider2D other)
{
if(other.gameObject.tag == "PlatformGroup")
player.SetParent(null);
}
What you should do is:
Create an empty GameObject, and you make your platform child of this
empty GameObject. Tag it as PlatformGroup.
You add the script to move the platform to this EmptyGame Object,
instead of using it in the platform itself.
Then add a collider to empty gameobject(PlatformGroup) and another to the Player. Set the one of the player as trigger.
Add the code above to your player controller.
Now, when the Player jumps over the Platform if will become a child of the same GameObject of the platform and they will move together without any deformations in the GameObject. Also when the player leaves the platform, walking or jumping out of it, it will stop being child.
I'm making a game (similar to Subway Surfers), and I have a floor made of many small cubes. And I want to make my game do something when the player stops colliding with the floor. But when I use OnTriggerExit (Collider other) I never know if the player stops colliding the floor or just moves from one piece of the floor to another:
OnTriggerExit (Collider other){
if (other.tag == "floor") {
if(/*Object isn't coliding with any other object with the tag "floor" (Or simply isn't coliding with the other piece of the floor) */){
//Do something
}
}
}
It depends on the needs of the game. Since you named Subway Surfer, I would go with the z-coordinate of the player.
I would add the heightFromGround field to the player class (calculated as the difference on the z-axis between the player and the platform underneath).
Then, if heightFromGround is higher than a threshold, you know the player is jumping.
This also allows you to control the Animation of the character based on it's height from the ground (so he can prepare to land) and transition to the running state.
To have different platforms at different heights, you need to know the platform currently underneath the player at runtime.
This is just an approach to avoid collision checking.
If you don't need that level of control on Animations and prefer to keep using collisions, you can simply add a field int touchingPlatforms = 1; and add 1 to it OnCollisionEnter, subtract 1 from it OnCollisionExit. The player is jumping if touchingPlatforms is 0.
I'm using the following code to make my player move along with moving platforms, and it works in that it does indeed make you the child of the platform and move along with it while on it, however the player will move faster than the platform.
The platform is moving left then right between two points repeatedly, but the player moves quicker, so will slide along the platform, and you obviously might fall off therefore.
void OnCollisionEnter2D (Collision2D other) {
if(other.gameObject.tag == "moving") {
transform.parent = other.transform.parent;
}
}
void OnCollisionExit2D (Collision2D other) {
transform.parent = null;
}
Now I figure that this code is fine because as I have said you become the child of the platform and move along which is all this does.
Was going to delete this but I thought it'd be best just to leave it here in case anyone has the same issue.
After removing friction from the platform and the player, everything happens as expected, and I can move with the moving platforms without pressing anything.