Reputation: 511
I'm trying to make a dotted line that shows where the balls going to land and reflect from there. I'm using unity's physics system.
I think something is wrong with circle cast and line renderer.
The balls are spawning thru wherever i click with my mouse. So i do not see any problem on BallCreate() function.
Here is the problem.
As you can see in the picture, balls instantiated on transform.position and going thru hit.point. Somehow line-renderer and ball direction is not the same. There is always a little bit difference(Sometimes more).
The code is below:
I'm trying to fix this for a week, any help means so much.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public Transform BallPrefab = null;
bool ShootDirected = true;
Vector3 mousePos;
private LineRenderer linerender;
RaycastHit2D hitx;
private Vector3 dir;
private Vector3 origin;
void Start()
{
linerender = GetComponent<LineRenderer>();
}
void Update()
{
mousePos = new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y, 0);
//Direction according to mouse position.
dir = mousePos - transform.position;
origin = transform.position;
//First hit point 0.3307159f is the radius of the ball.
RaycastHit2D hit = Physics2D.CircleCast(origin, 0.3307159f, dir, 100f, 1 << 9 | 1<<10);
if (hit.collider != null)
{
//Stored reflected hit point.
Vector2 reflectDir = Vector2.Reflect(dir, hit.normal);
//Then start second ray from hit point thru reflected hit point.
RaycastHit2D SecondHit = Physics2D.CircleCast(hit.point, 0.3307159f, reflectDir, 100, 1 << 9 | 1<<10);
//Draw lines beetween origin, hit.point and secondhit point.
linerender.SetPosition(0, origin);
linerender.SetPosition(1, hit.point);
linerender.SetPosition(2, SecondHit.point);
}
//Create 50 balls when mouse clicked.
if (Input.GetMouseButtonUp(0))
{
ShootDirected = true;
StartCoroutine("BallCreate");
}
}
IEnumerator BallCreate()
{
Vector3 shootDirection = new Vector3(0,0,0);
//Create 50 balls
for (int i = 0; i < 50; i++)
{
Transform ball = Instantiate(BallPrefab, transform.position, Quaternion.identity) as Transform;
Rigidbody2D rb = ball.GetComponent<Rigidbody2D>();
if (ShootDirected)
{
//Set shootDirection to mouse position
shootDirection = Input.mousePosition;
shootDirection.z = 0.0f;
shootDirection = Camera.main.ScreenToWorldPoint(shootDirection);
//Get direction.
shootDirection = (shootDirection - transform.position);
ShootDirected = false;
}
//Apply force to each ball thru mouse direction.
rb.velocity = new Vector2(shootDirection.x, shootDirection.y);
rb.velocity = 7f * (rb.velocity.normalized);
yield return new WaitForSeconds(0.08f);
}
}
}
Upvotes: 0
Views: 1756
Reputation: 511
Found the problem with help of MelvMay on Unity Technologies.
Simply change
`RaycastHit2D SecondHit = Physics2D.CircleCast(hit.point, 0.3307159f, reflectDir, 100, 1 << 9 | 1<<10);`
to
RaycastHit2D SecondHit = Physics2D.CircleCast(hit.centroid, 0.3307159f, reflectDir, 100, 1 << 9 | 1<<10);
MelvMay's explanation;
If you look at the RaycastHit2D docs you'll see both a "point" property (which you're using) which is the actual position the shapes intersected. For a ray this is obvious as it has no size. For a shape such as a circle, this isn't the position the circle is when it intersects, it's the point on its exterior. For all the casts, you can use the "centroid" property for this. This returns the position of the shape when it is in contact. For a Line/Ray, both the "point" and "centroid" properties are identical but for (say) a circle, box, capsule or polygon, these will be different.
Upvotes: 2