I’ve been trying to make the same effect as the Mario Question Mark Box. Not to spawn anything but the up and down animation on hit. I’ve been using a box(tile) with a RigidBody2D with a Dynamic BodyType so I can use gravity to make the effect. I have the box collider side detection done so I know when the Player touches the bottom or the top of the box . I have 2 problems right now:
When I step on the top of the Box the Y axis + Gravity makes the box fall down. I’ve tried to Freeze the Y axis onCollisionEnter from the top but It has a certain delay and the box still gets out of place by a couple decimals.
When I hit the Box from the Bottom (and the up and down effect occurs) I can’t make the box get to the original Position smoothly, it simply just falls down with gravity.
Do you have any suggestions on this? I’m new to Unity but this effect shouldn’t be difficult to do.
2019.2 onwards now includes a stable XY position constraint for 2D that makes it completely immovable in the respective axis. So you should be able to use that then turn it off when you want gravity to take effect.
If you’re using an earlier version and cannot upgrade then maybe use a Kinematic body-type then switch it to dynamic when you want it to move under the influence of gravity?
I struggled with this quite a bit as well, here is what I did:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ButtonTrigger : MonoBehaviour {
public float bounceHeight = 0.5f;
public float bounceSpeed = 4f;
private Vector2 originalPosition;
private bool canBounce = true;
private bool upHit;
private BoxCollider2D col;
// Use this for initialization
void Start()
{
col = GetComponent<BoxCollider2D>();
originalPosition = transform.localPosition;
upHit = false;
ColliderVerify();
}
public void ButtonTriggerBounce()
{
if (canBounce)
{
canBounce = false;
StartCoroutine(Bounce());
}
}
void ColliderVerify()
{
if (col == null)
{
col = gameObject.AddComponent(typeof(BoxCollider2D)) as BoxCollider2D;
Debug.Log("We did not have col so we are adding it");
}
else
return;
}
private void OnCollisionEnter2D(Collision2D other)
{
if(other.collider.tag == "Player")
{
Debug.Log("We have hit the player");
ButtonTriggerBounce();
}
}
IEnumerator Bounce()
{
while (true)
{
transform.localPosition = new Vector2(transform.localPosition.x, transform.localPosition.y + bounceSpeed * Time.deltaTime);
if (transform.localPosition.y >= originalPosition.y + bounceHeight)
{
break;
}
yield return null;
}
while (true)
{
transform.localPosition = new Vector2(transform.localPosition.x, transform.localPosition.y - bounceSpeed * Time.deltaTime);
if (transform.localPosition.y <= originalPosition.y)
{
transform.localPosition = originalPosition;
break;
}
upHit = true;
yield return null;
}
}
}
This should work, but I had to edit mine so it wasnt confusing as I have 3 different directions my buttons can bounce depending on how the gravity is rotated. The code is just for basic gravity and the box popping up and then back down again.
Here is the video i used:
That page has a whole tutorial series about cloning a Mario game so it may be useful for you.
Never change the Transform when using physics components. It’s the job of Rigidbody(2D) to do that. It’s your proxy to the Transform. This is what Rigidbody2D.MovePosition is for.