Unity: Knockback my player - c#

I have this script attached to an object, if my player encounters that object it will be knocked back. I have six directions on which it will be knocked back. This image will show you the different direction of which my player may get knock back. My problem: X=0,Y=1 (up) and X=0,Y=-1 (down) doesn't work, however every other velocity works. How can I also include the directions of X=0,Y=1 and X=0,Y=-1. Thank you and here is my code:
public class Knockback: MonoBehaviour
{
public float xForceToAdd;
public float yForceToAdd;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
//Store the vector 2 of the location where the initial hit happened;
Vector2 initialHitPoint = new Vector2(other.gameObject.transform.position.x, other.gameObject.transform.position.y);
float xForce = 0;
float yForce = 0;
//Grab our collided with objects rigibody
Rigidbody2D rigidForForce = other.gameObject.GetComponent < Rigidbody2D > ();
//Determine left right center of X hit
if (initialHitPoint.x > (this.transform.position.x + (this.transform.localScale.x / 3)))
{
xForce = 1;
}
else if (initialHitPoint.x < (this.transform.position.x - (this.transform.localScale.x / 3)))
{
xForce = -1;
}
else
{
xForce = 0;
}
if (initialHitPoint.y > (this.transform.position.y + (this.transform.localScale.y / 3)))
{
yForce = 1;
}
else if (initialHitPoint.y < (this.transform.position.y - (this.transform.localScale.y / 3)))
{
yForce = -1;
}
else
{
yForce = 0;
}
rigidForForce.velocity = new Vector2(xForce * xForceToAdd, yForce * yForceToAdd);
}
}
}

Most probably, it doesn't see the if statements of y part. Use else if for all if statements after the first one. Try this:
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
//Store the vector 2 of the location where the initial hit happened;
Vector2 initialHitPoint = new Vector2(other.gameObject.transform.position.x, other.gameObject.transform.position.y);
float xForce = 0;
float yForce = 0;
//Grab our collided with objects rigibody
Rigidbody2D rigidForForce = other.gameObject.GetComponent < Rigidbody2D > ();
//Determine left right center of X hit
if (initialHitPoint.x > (this.transform.position.x + (this.transform.localScale.x / 3))
&& initialHitPoint.y > (this.transform.position.y + (this.transform.localScale.y / 3)))
{
xForce = 1;
yForce = 1;
}
else if (initialHitPoint.x > (this.transform.position.x + (this.transform.localScale.x / 3))
&& initialHitPoint.y < (this.transform.position.y - (this.transform.localScale.y / 3)))
{
xForce = 1;
yForce = -1;
}
else if (initialHitPoint.x < (this.transform.position.x + (this.transform.localScale.x / 3))
&& initialHitPoint.y > (this.transform.position.y - (this.transform.localScale.y / 3)))
{
xForce = -1;
yForce = 1;
}
else if (initialHitPoint.x < (this.transform.position.x + (this.transform.localScale.x / 3))
&& initialHitPoint.y < (this.transform.position.y - (this.transform.localScale.y / 3)))
{
xForce = -1;
yForce = -1;
}
else if (initialHitPoint.x > (this.transform.position.x + (this.transform.localScale.x / 3))
&& initialHitPoint.y == (this.transform.position.y - (this.transform.localScale.y / 3)))
{
xForce = 1;
yForce = 0;
}
else if (initialHitPoint.x < (this.transform.position.x + (this.transform.localScale.x / 3))
&& initialHitPoint.y == (this.transform.position.y - (this.transform.localScale.y / 3)))
{
xForce = -1;
yForce = 0;
}
else if (initialHitPoint.x == (this.transform.position.x + (this.transform.localScale.x / 3))
&& initialHitPoint.y < (this.transform.position.y - (this.transform.localScale.y / 3)))
{
xForce = 0;
yForce = -1;
}
else if (initialHitPoint.x == (this.transform.position.x + (this.transform.localScale.x / 3))
&& initialHitPoint.y > (this.transform.position.y - (this.transform.localScale.y / 3)))
{
xForce = 0;
yForce = 1;
}
else
{
xForce = 0;
yForce = 0;
}
rigidForForce.velocity = new Vector2(xForce * xForceToAdd, yForce * yForceToAdd);
}
}

Related

Collision detection problems in my Tank Trouble like game in C#

I am doing a Tank Trouble (aka. AZ) like game in c#, winforms application.
I am drawing to a picturebox, the walls are stored in a list, each wall has a specified thickness, a starting and ending point and a boolean which tells if the wall is vertical (true), or if it is horizontal (the bool is false)
My collision detector goes trough the list and checks if it collides with one of them, then sets the respective booleans if collision was detected in a direction (up, down, left, right)
My problem is, that sometimes there are false positives, and false negatives too, there are cases, when it stucks while no walls are near, sometimes goes through the walls.
Could somebody give some suggestions how to improve it?
Is there a more optimal way to do it?
Here is my code
public void MoveTank()
{
// Calculate velocity from angle and base speed
Vx = (float)(moveSpeed * Math.Sin((angle * 0.0174532925)));
Vy = (float)(moveSpeed * Math.Cos((angle * 0.0174532925)));
CollisionDetector();
if (up == true)
{
Vy = 0;
}
if (down == true)
{
Vy = 0;
}
if (left == true)
{
Vx = 0;
}
if (right == true)
{
Vx = 0;
}
up = false;
down = false;
left = false;
right = false;
if (tUp) //if up key is pressed
{
tankCo.Y -= Vy;
tankCo.X += Vx;
}
if (tDown) //if down key is pressed
{
tankCo.Y += Vy;
tankCo.X -= Vx;
}
if (tLeft) //rotate left
{
angle -= angV;
if (angle < 0)
{
angle = 360 + angle;
}
angle = angle % 360;
img = RotateImage(OldImg, angle);
}
if (tRight) //rotate right
{
angle += angV;
angle = angle % 360;
if (angle < 0)
{
angle = 360 + angle;
}
img = RotateImage(OldImg, angle);
}
}
public void CollisionDetector()
{
foreach (Walls.Brick w in GameWindow.wall.allWalls)
{
if(w.vertical == true)
{
if (this.tankCo.X > w.wallStart.X && this.tankCo.X + this.Vx < w.wallStart.X)
{
this.left = true;
}
else if (this.tankCo.X < w.wallStart.X && this.tankCo.X + this.Vx > w.wallStart.X)
{
this.right = true;
}
}
else if(w.vertical == false)
{
if (this.tankCo.Y > w.wallStart.Y && this.tankCo.Y + this.Vy < w.wallStart.Y)
{
this.up = true;
}
else if (this.tankCo.Y < w.wallStart.Y && this.tankCo.Y + this.Vy > w.wallStart.Y)
{
this.down = true;
}
}
}
}
if it isn't enough here is my entire repository
https://github.com/SorbanElod/CSharp/tree/main/SPANzer
After some work here is what i came up with
Thank you for your help
public void MoveTank()
{
if(tUp == tDown)
{
Vx = 0;
Vy = 0;
}
else if (tUp)
{
// Calculate velocity from angle and base speed
Vx = (float)(moveSpeed * Math.Sin((angle * 0.0174532925))); //that ugly number is PI/180
Vy = -(float)(moveSpeed * Math.Cos((angle * 0.0174532925)));
}
else if (tDown)
{
// Calculate velocity from angle and base speed
Vx = -(float)(moveSpeed * Math.Sin((angle * 0.0174532925)));
Vy = (float)(moveSpeed * Math.Cos((angle * 0.0174532925)));
}
//If it collides then one component of the velocity will be removed (Vx or Vy)
CollisionDetector();
tankCo.X += Vx;
tankCo.Y += Vy;
if (tLeft)
{
angle -= angV;
if (angle < 0)
{
angle = 360 + angle;
}
angle = angle % 360;
img = RotateImage(OldImg, angle);
}
if (tRight)
{
angle += angV;
angle = angle % 360;
if (angle < 0)
{
angle = 360 + angle;
}
img = RotateImage(OldImg, angle);
}
}
public void CollisionDetector()
{
foreach (Walls.Brick w in GameWindow.wall.allWalls)
{
if(w.vertical == false) // horizontal wall
{
//check if tank can collide with wall's side
if (tankCo.X >= w.wallStart.X && tankCo.X <= w.wallEnd.X)
{
//collision with tehe wall above
if (tankCo.Y > w.wallStart.Y && tankCo.Y + Vy < w.wallStart.Y)
{
Vy = 0;
}
//collision with the wall below
if (tankCo.Y + imgSize < w.wallStart.Y && tankCo.Y + imgSize + Vy > w.wallStart.Y)
{
Vy = 0;
}
}
//checks if tank can collide with the walls end
if (tankCo.Y < w.wallStart.Y && tankCo.Y + imgSize > w.wallStart.Y)
{
//collision with the right end
if (tankCo.X > w.wallEnd.X && tankCo.X + Vx < w.wallEnd.X)
{
Vx = 0;
}
//collision with the left end
if (tankCo.X + imgSize < w.wallStart.X && tankCo.X + imgSize + Vx > w.wallStart.X)
{
Vx = 0;
}
}
}
else if(w.vertical == true) //vertical
{
//check if tank can collide with wall's side
if (tankCo.Y >= w.wallStart.Y && tankCo.Y <= w.wallEnd.Y)
{
//collision with the wall from right
if (tankCo.X > w.wallStart.X && tankCo.X + Vx < w.wallStart.X)
{
Vx = 0;
}
//collision with the wall from left
if (tankCo.X + imgSize < w.wallStart.X && tankCo.X + imgSize + Vx > w.wallStart.X)
{
Vx = 0;
}
}
//checks if tank can collide with the walls end
if (tankCo.X < w.wallStart.X && tankCo.X + imgSize > w.wallStart.X)
{
//collision with the bottom end
if (tankCo.Y > w.wallEnd.Y && tankCo.Y + Vy < w.wallEnd.Y)
{
Vy = 0;
}
//collision with top end
if (tankCo.Y + imgSize < w.wallStart.Y && tankCo.Y + imgSize + Vy > w.wallStart.Y)
{
Vy = 0;
}
}
}
}
}
It may be a bit complicated but it works for me

How to create a score multiplier?

I am a making an endless skiing game, and already have a scoring system, however i want to add a score multiplier based on the number of consecutive tricks done without touching the ground. here's my script so far:
public class tricksScore : MonoBehaviour
{
private float flips = 0;
private float deltaRotation = 0;
private float currentRotation = 0;
private float WindupRotation = 0;
public static Rigidbody2D rigbod;
public Text scores;
private int trickscore;
private int iflip;
private int oldscore;
private int incInScore;
public float speed;
private float counter;
private int flipscore;
private int rockDestroy;
private bool grounded;
private int multiplier = 1;
// Collision2D coll;
// Start is called before the first frame update
void Start()
{
speed = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>().speed;
scores = GameObject.Find("score").GetComponent<Text>();
rigbod = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
grounded = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>().grounded;
}
// Update is called once per frame
void Update()
{
rigbod.velocity = new Vector2(speed, rigbod.velocity.y);
deltaRotation = currentRotation - rigbod.transform.eulerAngles.z;
currentRotation = rigbod.transform.eulerAngles.z;
if (deltaRotation >= 300) deltaRotation -= 360;
if (deltaRotation <= -300) deltaRotation += 360;
WindupRotation += (deltaRotation);
flips = WindupRotation / 340;
iflip = (int)flips;
iflip = iflip * -1;
flipscore = iflip * 10;
trickscore = flipscore + rockDestroy;
scores.text = "score " + (trickscore * multiplier);
incInScore = trickscore - oldscore;
if (incInScore >= 10)
{
oldscore = trickscore;
}
//speed += (Mathf.Round(incInScore)) / 100.0f;
if (incInScore > 1 && incInScore <= 10)
{
speed = speed + 0.15f;
counter += 3f;
}
if (incInScore > 10 && incInScore <= 20)
{
speed = speed + 0.25f;
counter += 3f;
}
if (incInScore > 20 && incInScore <= 50)
{
speed = speed + 0.50f;
counter += 3f;
}
if (incInScore > 50 && incInScore <= 100)
{
speed = speed + 0.75f;
counter += 3f;
}
if (incInScore > 100 && incInScore <= 200)
{
speed = speed + 1f;
counter += 3.5f;
}
if (incInScore > 200)
{
speed = speed + 2f;
counter += 4f;
}
if (incInScore > 5 && grounded == false)
{
multiplier = multiplier + 1;
}
else if (grounded == true)
{
multiplier = 1;
}
if (speed > 5.15f)
{
speed -= 0.05f * Time.deltaTime;
}
else if (speed == 5.15f)
{
speed = 5.15f;
}
counter -= 1.0f * Time.deltaTime;
if (counter < 0)
{
counter = 0;
}
if (incInScore >= 10)
{
incInScore = 0;
}
if (incInScore < 0)
{
incInScore = incInScore * -1;
}
}
private void OnCollisionEnter2D(Collision2D coll)
{
//counter = GameObject.FindGameObjectWithTag("Player").GetComponent<tricksScore>().counter;
if (counter > 0)
{
if (coll.collider.tag == "rock")
{
Destroy(coll.gameObject);
speed = speed + 0.15f;
rockDestroy = rockDestroy + 5;
counter = counter + 2f;
}
}
}
}
I know the scripts dirty, but hopefully its still comprehensible for you all. thanks in advance for the help.
Your ground boolean is only set in start, so it will almost always be false. Add the check statement in the update function, as when you set a variable with this property, it will only take the value at that time, it will not automatically update.

How can I set the newPositions distance to be shorter closer to the original squadMembers positions?

I have 3 formations:
In each formation I'm calculating new positions to move to and add them to the List newPositions.
private void FormationTriangle()
{
newpositions = new List<Vector3>();
int height = Mathf.CeilToInt((Mathf.Sqrt(8 * squadMembers.Count + 1f) - 1f) / 2);
int slots = (int)(height * (height + 1f) / 2f);
float verticalModifier = 1.25f; // * 1.25f to increase horizontal space
float horizontalModifier = 0.8f; // * 0.8f to decrease "vertical" space
float width = 0.5f * (height - 1f);
Vector3 startPos = new Vector3(width * horizontalModifier, 0f, (float)(height - 1f) * verticalModifier);
int finalRowCount = height - slots + squadMembers.Count;
for (int rowNum = 0; rowNum < height && newpositions.Count < squadMembers.Count; rowNum++)
{
for (int i = 0; i < rowNum + 1 && newpositions.Count < squadMembers.Count; i++)
{
float xOffset = 0f;
if (rowNum + 1 == height)
{
// If we're in the last row, stretch it ...
if (finalRowCount != 1)
{
// Unless there's only one item in the last row.
// If that's the case, leave it centered.
xOffset = Mathf.Lerp(
rowNum / 2f,
-rowNum / 2f,
i / (finalRowCount - 1f)
) * horizontalModifier;
}
}
else
{
xOffset = (i - rowNum / 2f) * horizontalModifier;
}
float yOffset = (float)rowNum * verticalModifier;
Vector3 position = new Vector3(
startPos.x + xOffset, 0f, startPos.y - yOffset);
newpositions.Add(position);
}
}
move = true;
formation = Formation.Square;
}
private Vector3 FormationSquarePositionCalculation(int index) // call this func for all your objects
{
float posX = (index % columns) * gaps;
float posY = (index / columns) * gaps;
return new Vector3(posX, posY);
}
private void FormationSquare()
{
newpositions = new List<Vector3>();
quaternions = new List<Quaternion>();
for (int i = 0; i < squadMembers.Count; i++)
{
Vector3 pos = FormationSquarePositionCalculation(i);
//squadMembers[i].transform.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);
squadMembers[i].transform.Rotate(new Vector3(0, -90, 0));
newpositions.Add(new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y));
}
move = true;
squareFormation = true;
formation = Formation.Circle;
}
private Vector3 FormationCirclePositionCalculation(Vector3 center, float radius, int index, float angleIncrement)
{
float ang = index * angleIncrement;
Vector3 pos;
pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
pos.y = center.y;
return pos;
}
private void FormationCircle()
{
newpositions = new List<Vector3>();
quaternions = new List<Quaternion>();
Vector3 center = transform.position;
float radius = (float)circleRadius / 2;
float angleIncrement = 360 / (float)numberOfSquadMembers;
for (int i = 0; i < numberOfSquadMembers; i++)
{
Vector3 pos = FormationCirclePositionCalculation(center, radius, i, angleIncrement);
var rot = Quaternion.LookRotation(center - pos);
if (Terrain.activeTerrain == true)
pos.y = Terrain.activeTerrain.SampleHeight(pos);
pos.y = pos.y + yOffset;
newpositions.Add(pos);
quaternions.Add(rot);
}
move = true;
squareFormation = false;
formation = Formation.Triangle;
}
Then I'm moving the squadMembers to the newPositions:
private void MoveToNextFormation()
{
if (randomSpeed == false)
{
if (step.Length > 0)
step[0] = moveSpeed * Time.deltaTime;
}
for (int i = 0; i < squadMembers.Count; i++)
{
squadMembers[i].transform.LookAt(newpositions[i]);
if (Vector3.Distance(squadMembers[i].transform.position, newpositions[i]) > 30f)
{
if (randomSpeed == true)
{
squadMembers[i].transform.position =
Vector3.MoveTowards(squadMembers[i].transform.position, newpositions[i], step[i]);
}
else
{
squadMembers[i].transform.position =
Vector3.MoveTowards(squadMembers[i].transform.position, newpositions[i], step[0]);
}
}
if (Vector3.Distance(squadMembers[i].transform.position, newpositions[i]) < threshold)
{
if (squareFormation == true)
{
Vector3 degrees = new Vector3(0, 0, 0);
Quaternion quaternion = Quaternion.Euler(degrees);
squadMembers[i].transform.rotation = Quaternion.Slerp(squadMembers[i].transform.rotation, quaternion, rotateSpeed * Time.deltaTime);
}
else
{
squadMembers[i].transform.rotation = Quaternion.Slerp(squadMembers[i].transform.rotation, quaternions[i], rotateSpeed * Time.deltaTime);
}
}
}
}
But if I want that the squadMembers will not move at all but will change to the next formation on the same position they are ? Or maybe to move just a little bit for example to distance 20 or 5 or 30 or 300 ?
I tried to add a distance check for the move:
if (Vector3.Distance(squadMembers[i].transform.position, newpositions[i]) > 30f)
So they are changing to the next formation when the distance more then 30.
But then the formation is not looking good. If for example it's the square formation the formation after they finished moving looks like a wave.
Screenshot example:
Wave formation

Unity Mobile Control for 2 players (Counting touches)

I am trying to implement controls for 2 players on one screen
Here is a code:
if (playerNum == 1) {
if (Input.touchCount > 0) {
for (int i = 0; i < 1; i++) {
if (Input.GetTouch (i).position.x > 0 && Input.GetTouch (i).position.x < Screen.width / 4) {
transform.Rotate (Vector3.forward * 300f * Time.deltaTime);
}
if (Input.GetTouch (i).position.x > Screen.width / 4 && Input.GetTouch (i).position.x < Screen.width / 2) {
transform.Rotate (Vector3.back * 300f * Time.deltaTime);
}
}
}
} else {
if (Input.touchCount > 0) {
for (int i = 0; i < 1; i++) {
if (Input.GetTouch (i).position.x > Screen.width / 2 && Input.GetTouch (i).position.x < Screen.width * 3 / 4) {
transform.Rotate (Vector3.back * 300f * Time.deltaTime);
}
if (Input.GetTouch (i).position.x > Screen.width * 3 / 4 && Input.GetTouch (i).position.x < Screen.width) {
transform.Rotate (Vector3.forward * 300f * Time.deltaTime);
}
}
}
}
This is how it looks like schematic:
With
if (Input.touchCount > 0) {
for (int i = 0; i < 1; i++)
I can get only one tap, not only for red or green zone, but for full screen. If value is higher, i < 5 (for example), I can hold 4 fingers only in one zone and rotate 4 times faster.
How can I change the code to count only one tap for each zone?
I don't have any emulator at hand but I believe the following should work:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
public float Speed = 300.0f;
void Update()
{
var w = Screen.width / 4.0f;
var h = Screen.height;
var r1 = new Rect(w * 0, 0.0f, w, h);
var r2 = new Rect(w * 1, 0.0f, w, h);
var r3 = new Rect(w * 2, 0.0f, w, h);
var r4 = new Rect(w * 3, 0.0f, w, h);
var t1 = Input.GetTouch(0);
var tc = Input.touchCount;
if (tc == 1 && t1.phase == TouchPhase.Began)
{
var pos = t1.position;
var dir = Vector3.zero;
if (r1.Contains(t1.position))
dir = Vector3.back;
if (r2.Contains(pos))
dir = Vector3.forward;
transform.Rotate(dir * Speed);
}
}
}
So, I have created 4 variable: AZone,BZone,CZone,DZone. Now i can control every touch. In my example I'm rotating only if AZone equals 1. It works pretty good, exactly what i needed. Thanks for helping me in solving this problem.
if (Input.touchCount > 0) {
AZone = 0;
BZone = 0;
//Debug.Log (Input.touchCount);
for (int i = 0; i < Input.touchCount; i++) {
if (Input.GetTouch (i).position.x > 0 && Input.GetTouch (i).position.x < Screen.width / 4) {
AZone += 1;
if (AZone == 1) {
transform.Rotate (Vector3.forward * 300f * Time.deltaTime);
}
//Debug.Log (AZone);
}
if (Input.GetTouch (i).position.x > Screen.width / 4 && Input.GetTouch (i).position.x < Screen.width / 2) {
BZone += 1;
if (BZone == 1) {
transform.Rotate (Vector3.back * 300f * Time.deltaTime);
}
}
}
}

Unity: Knockback my player along the Y-axis

I don't think the Y-axis for my code is working. Iv'e tried increasing the yForceToAdd and the localScale.y but (when I collide with the object that has this script attached to it) my player only goes (when I collide at the top of the object) X=1, Y=1 or X=-1, Y=1 and not X=0, Y=1 as well. the same problem with the bottom of my object X=0, Y=-1 doesn't seem to work either. can someone help with this problem?
public float xForceToAdd;
public float yForceToAdd;
void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.tag == "Player")
{
//Store the vector 2 of the location where the initial hit happened;
Vector2 initialHitPoint = new Vector2(other.gameObject.transform.position.x, other.gameObject.transform.position.y);
float xForce = 0;
float yForce = 0;
//Grab our collided with objects rigibody
Rigidbody2D rigidForForce = other.gameObject.GetComponent < Rigidbody2D > ();
//Determine left right center of X hit
if (initialHitPoint.x > (this.transform.position.x + (this.transform.localScale.x / 3)))
{
xForce = 1;
}
else if (initialHitPoint.x < (this.transform.position.x - (this.transform.localScale.x / 3)))
{
xForce = -1;
}
else
{
xForce = 0;
}
if (initialHitPoint.y > (this.transform.position.y + (this.transform.localScale.y / 3)))
{
yForce = 1;
}
else if (initialHitPoint.y < (this.transform.position.y - (this.transform.localScale.y / 3)))
{
yForce = -1;
}
else
{
yForce = 0;
}
rigidForForce.velocity = new Vector2(xForce * xForceToAdd, yForce * yForceToAdd);
}
}
The logic in computing the margins where the hit is being registered is wrong. For example in this.transform.localScale.y / 3, the localScale.y with probably give you 1.0f, but what you meant inside the expression (this.transform.position.y + (this.transform.localScale.y / 3) is that you want the y-center of the object, plus one-third of it's height. However, this.transform.localScale.y will only give you a "multiplier" so to say. In a unscaled object, transfomr.localScale will be 1.0, so you would be adding transform.position.y + (1.0f / 3), which is probably not what you want. You must multipliy this with the actual height of the object to get what you want. This can be done by either relying on the Sprite or a Collider, e.g. a BoxCollider2D. Modified logic (I also divided by 3f instead of by 3 to make it a more accurate floating point division..):
public float xForceToAdd;
public float yForceToAdd;
void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.tag == "Player")
{
//Store the vector 2 of the location where the initial hit happened;
Vector2 initialHitPoint = new Vector2(other.gameObject.transform.position.x, other.gameObject.transform.position.y);
float xForce = 0;
float yForce = 0;
//Grab our collided with objects rigibody
Rigidbody2D rigidForForce = other.gameObject.GetComponent < Rigidbody2D > ();
//Get the width and height of this object by looking up the size of the box collider
//Alternatively, use constant values here or rely on the Sprite.
float width = GetComponent<BoxCollider2D>().size.x;
float height = GetComponent<BoxCollider2D>().size.y;
//Determine left right center of X hit
if (initialHitPoint.x > (this.transform.position.x + width * (this.transform.localScale.x / 3f)))
xForce = 1;
else if (initialHitPoint.x < (this.transform.position.x - width* (this.transform.localScale.x / 3f)))
xForce = -1;
else
xForce = 0;
if (initialHitPoint.y > (this.transform.position.y + height * (this.transform.localScale.y / 3f)))
yForce = 1;
else if (initialHitPoint.y < (this.transform.position.y - height * (this.transform.localScale.y / 3f)))
yForce = -1;
else
yForce = 0;
Debug.Log(string.Format("Hit Point X: {0}. Left Boundary: {1} Right Boundary: {2}, xForce = {3}", initialHitPoint.x, (this.transform.position.x - width*this.transform.localScale.x / 3f), (this.transform.position.x + width * (this.transform.localScale.x / 3f)), xForce));
rigidForForce.velocity = new Vector2(xForce * xForceToAdd, yForce * yForceToAdd);
}
}

Categories