I'm trying to make a 2D platform game where my character makes a ground check before jumping using Physics2D.BoxCast & some of the platforms have Capsule Collider 2D & others have Box Collider 2D.
Everything works fine with the Box Collider but when it comes to Capsule Collider, Boxcast is not responding & my character can spam jump on those platforms. Here's my code for ground check,
public bool isGrounded()
{
RaycastHit2D raycastHit = Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector3.down, castDist, ground);
return raycastHit.collider != null;
}
How can I resolve this issue? Any way to detect both BoxCollider & CapsuleCollider?
I got it, the castDist variable was causing the issue. It was set to 5 so the detection at bottom was far more than enough, reducing it to 0.1 solved the issue.
Related
I am making an endless platformer.
private bool IsGrounded()
{
RaycastHit2D raycastHit2d = Physics2D.BoxCast(boxCollider2d.bounds.center, boxCollider2d.bounds.size, 0f, Vector2.down, 0.02f, platformsLayerMask);
return raycastHit2d.collider != null;
}
This is my ground check.
But I am having issues. IsGrounded is set to true, when head (top) of player is hitting bottom of platform (Basically Box cast is detecting top even though direction is set to down.
Like this:
Player infinitely jumping under platform
Thanks, and please tell me if you need more info! (:
RaycastHit2D has field Vector2 normal, you can check if it points up to be sure that the closest geometry is below you. But check if such approach works properly when you stand near the wall (normal can point left or right). In that special case I'd cast one more regular ray down to check for ground.
Thank you.
Anyways, the platforms were slightly affected by gravity and physics, so they were slightly rotated causing the issue.
I can think of what objects I will use in the game and add them a box collider or mesh collider and start setting them up. Or I could use maybe raycast and detect the distance from the objects I want to avoid walking through ? Is that logic to use distance calculation with raycast ?
void FixedUpdate()
{
Vector3 direction = new Vector3(transform.position - lastPosition);
Ray ray = new Ray(lastPosition, direction);
RaycastHit hit;
if (Physics.Raycast(ray, hit, direction.magnitude))
{
// Do something if hit
}
this.lastPosition = transform.position;
}
Not sure if this is the right script to put on the player. Maybe need to use layer ? But the logic is that if the player is for example 0.3f distance form the object that the player will stop moving forward.
Using unity you don't really want to be doing any of this stuff from the code behind, instead you'd have a RigidBody or RigidBody2D component on your "player", and then a box Collider or mesh collider (or the 2d versions of those) on your collision objects.
This will handle all collisions and stop the player when they hit that object.
Another word of advice is, when handling collisions in the backend you don't want to use FixedUpdate as if an object is travelling fast enough it will pass through the collider between updates
I have a small piece of code to make a sprite (in a 3D world) always face the camera (It has to be in 3D space).
public class CS_CameraFacingBillboard : MonoBehaviour {
private Camera m_Camera;
private void Start()
{
m_Camera = Camera.main;
}
void Update()
{
transform.LookAt(transform.position + m_Camera.transform.rotation *
Vector3.forward, m_Camera.transform.rotation * Vector3.up);
}
}
This code ensures the sprite is always facing the camera, causing it to lean backwards as the camera in above the sprite facing down in a 45 degree agle. When I put a rigidbody on the sprite, the sprite moves on its own towards the direction its leaning. The rigidbody works fine without this code attached.
How can I have a sprite that always faces the camera, and has a rigidbody attached?
It seems you've left the rigidbody as Dynamic, you should set it to Kinematic.
EDIT: After you comments, I checked myself inside Unity, and probably I've recreated the behaviour you described. It happens to me too IF I use a Box Collider on the sprite without locking its rigidbody rotation.
So you have three possible solutions:
Use a Box Collider and under Constraints of the rigidbody freeze the rotation:
Use a Sphere Collider (or another one that doesn't behave like the box one, you can check them out in play mode).
Split the components over two game object, a parent and a child. The parent will have all the components except the sprite renderer and the camera script, which will be on the child. This option is the most flexible and less restraining. You can have the box collider without freezing rotations, etc.
Another thing, you can avoid the use of the LookAt method, by simply using:
transform.rotation = m_Camera.transform.rotation;
they have the same outcome.
i am totally new to c# scripting and unity... i was trying something on unity and created this code and it's woring fine but some times it's just overlapping "wall" tagged object or even getting out of that circle i am using Edge collider 2D on it and polygon collider 2D on my shooter object and this script is attached to shooter object. check the screen shot for the bug.
void OnCollisionEnter2D (Collision2D collider){
if (collider.gameObject.tag == "wall") {
StartCoroutine (shooterscale());
collider.gameObject.GetComponent<bgAnimater> ().animateBg ();
if (turn) {
turn = false;
}
else {
turn = true;
}
}
}
I assume you are using Rigidbody2D on the shooter.
Make sure that Collision detection mode is set to Continous to avoid objects passing through each other.
From Docs:
When the Collision Detection is set to Continuous, GameObjects with
Rigidbody 2Ds and Collider 2Ds do not pass through each other during
an update. Instead, Unity calculates the first impact point of any of
the Collider 2Ds, and moves the GameObject there. Note that this takes
more CPU time than Discrete.
and
When you set the Collision Detection to Discrete, GameObjects with
Rigidbody 2Ds and Collider 2Ds can overlap or pass through each other
during a physics update, if they are moving fast enough. Collision
contacts are only generated at the new position.
Hope this helps
In a basic tutorial to make a 2D platformer I was given this bit of code:
if (Physics2D.Raycast(ray, out hit, Mathf.Infinity, collisionMask))
But Unity says you need Vector2s instead of Ray and out hit. Is there a way I could substitute Vectors for the same value and produce the same effect?
Here's the ray code if you want it:
ray = new Ray2D(new Vector2(x,y), new Vector2(x,dir));
The code is compiling now but it won't actually work (it's supposed to emulate gravity so the character will fall till they hit ground) but it just falls through the ground.
PlayerPhysics.cs
PlayerController.cs
In Unity the character has a Box Collider 2D which is correctly setup and the scripts are both attached and the platform has a Box Collider 2D correctly setup.
Your ray has an origin and direction components (both of which are vectors) so try this:
var hit = Physics2D.Raycast(ray.origin, ray.direction, Mathf.Infinity, collisionMask));