Hi I trying to do 2d collision in Unity without using any extensions.
Info about how my game is set up and What I want.
-Character moves left and right on x Axis, and up and down on y Axis.
-I wan’t my character to move to move freely like in games such as Link to the Past.
What Have I tried?
- I tried using a character controller with works but could not change the casual to to a box.
-Tried using a rigid-body but the physics were messing it up.
What am I doing Now?
-What I’m trying to do now is check in the direction the character is moving and see if its free. I’m having trouble with that.
I’v have been working on this for 2 weeks on my free time and I’m not getting anywhere so I’m asking for help.
Here is my Code so far witch does not work.
public float speed = 1;
private Vector3 velocity;
Vector3 position,
move,
testMove;
public float hAxis, yAxis;
void Update ()
{
ApplyInput();
Move();
}
bool SpaceFree(int x, int y, string ObjectTag)
{
GameObject[] O = GameObject.FindGameObjectsWithTag(ObjectTag);
testMove = new Vector3(x,0,0);
if (testMove.x > O[0].transform.position.x)
return true;
return true;
}
void ApplyInput()
{
hAxis = Input.GetAxisRaw("Horizontal");
yAxis = Input.GetAxisRaw("Vertical");
}
void Move()
{
position = transform.position;
velocity.x = hAxis * speed;
if (hAxis > 0.1 SpaceFree((int)position.x - (int)velocity.x,0, "RedCollision"))
{
transform.position = testMove * Time.deltaTime;
}
}
}
Thank You and any help will be appreciated. I just need rectangular collision. I don’t need nothing fancy like corner cutting.
You want an axis-aligned bounding box for something like a link to the past. I’d look into that. Math is really easy (literally next to circle or sphere the easiest there is). I would just use 3d bounding boxes for now, and the new update to unity (is coming soon) will support 2D collision natively.
I would add BoxCollider and then use raycast
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(objectToBeTested);
if ( Physics.Raycast(ray, out hit, 300f, /*optional layermask to e.g. exclude background on 2d game */ ) ) {
GameObject x = hit.transform.gameObject;
doStuff();
}
Also if you have some defined Rect area where you want to test collision this works as well. Edit: just noticed it might not work as i used it for RTS unit selection box which used screen coordinates
foreach (GameObject x in gameObjectsToBeTested) {
Vector3 pos = Camera.main.WorldToScreenPoint(x.transform.position);
Vector2 point = new Vector2(pos.x, Screen.height - pos.y);
if (selectionRect.Contains(point)) {
//x is on this point, do something
}
}
Thanks, Ill look into this.
Thanks Durazell for the help so far. I got it working for the most part. There are two glitches.
- When switching to a different collision object while moving diagonal the player may go through the object.
- Depending on how fast my character is moving he goes farther into the wall before stooping.
using UnityEngine;
using System.Collections;
public class RpgCharacterController : MonoBehaviour
{
//bool colliders
public bool collisionUp;
public bool collisionDown;
public bool collisionLeft;
public bool collisionRight;
//Speeds
public float moveSpeed;
Vector3 velocity;
//Input
float xAxis, yAxis;
void Update()
{
ApplyInput();
Move();
}
void ApplyInput()
{
//WADS / Arrow keys / Left Joystick
xAxis = Input.GetAxis("Horizontal");
yAxis = Input.GetAxis("Vertical");
}
void Move()
{
//Get Velocity
if (Input.GetKey(KeyCode.W) !collisionUp)
velocity.y = moveSpeed * Time.deltaTime;
if (Input.GetKey(KeyCode.S) !collisionDown)
velocity.y = -moveSpeed * Time.deltaTime;
if (Input.GetKey(KeyCode.A) !collisionLeft)
velocity.x = -moveSpeed * Time.deltaTime;
if (Input.GetKey(KeyCode.D) !collisionRight)
velocity.x = moveSpeed * Time.deltaTime;
transform.Translate(velocity);
velocity = Vector3.zero;
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Solid")
{
//Top-Left
Vector3 position = transform.position;
position.x-=0.25f;
if (Physics.Raycast (position,Vector3.up,0.3f)) collisionUp = true;
//Top-Right
position = transform.position;
position.x+=0.25f;
if (Physics.Raycast (position,Vector3.up,0.3f)) collisionUp = true;
//Top-Middile
position = transform.position;
if (Physics.Raycast (position,Vector3.up,0.3f)) collisionUp = true;
//Bottom-Left
position = transform.position;
position.x-=0.25f;
if (Physics.Raycast (position,Vector3.down,0.3f)) collisionDown = true;
//Bottom-Right
position = transform.position;
position.x+=0.25f;
if (Physics.Raycast (position,Vector3.down,0.3f)) collisionDown = true;
//Bottom-Middile
position = transform.position;
if (Physics.Raycast (position,Vector3.down,0.3f)) collisionDown = true;
//Left-Top
position = transform.position;
position.y+=0.25f;
if (Physics.Raycast (position,Vector3.left,0.3f)) collisionLeft = true;
//Left-Bottom
position = transform.position;
position.y-=0.25f;
if (Physics.Raycast (position,Vector3.left,0.3f)) collisionLeft = true;
//Left-Middile
position = transform.position;
if (Physics.Raycast (position,Vector3.left,0.3f)) collisionLeft = true;
//Right-Top
position = transform.position;
position.y+=0.25f;
if (Physics.Raycast (position,Vector3.right,0.3f)) collisionRight = true;
//Right-Bottom
position = transform.position;
position.y-=0.25f;
if (Physics.Raycast (position,Vector3.right,0.3f)) collisionRight = true;
//Right-Middile
position = transform.position;
if (Physics.Raycast (position,Vector3.right,0.3f)) collisionRight = true;
}
if (collision.gameObject.tag == "TransparancyCollision")
{
Color tempColor = collision.collider.renderer.material.color;
tempColor.a = 0.15f;
collision.collider.renderer.material.color = tempColor;
}
}
void OnCollisionExit(Collision collision)
{
if (collision.gameObject.tag == "Solid")
{
collisionUp = false;
collisionDown = false;
collisionLeft = false;
collisionRight = false;
}
if (collision.gameObject.tag == "TransparancyCollision")
{
Color tempColor = collision.collider.renderer.material.color;
tempColor.a = 1f;
collision.collider.renderer.material.color = tempColor;
}
}
}
Thanks so far for the help.