Raycast(Circlecast) and object direction not the same - c#

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.
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);
}
}
}

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.

Related

2D line renderer reflection issue - Unity

I make a 2d line renderer reflection on a specific object tag, it's working but only on the left side when on the right side the reflection is not showing, I don't have any idea why because when my script is on 3d it's working fine.
this is a script that I convert from 3D and I change it all to 2D.
public int reflections;
public float maxLength;
private LineRenderer lineRenderer;
public LayerMask layerMask;
private Ray2D ray;
private RaycastHit2D hit;
private void Awake()
{
lineRenderer = GetComponent<LineRenderer>();
}
private void Update()
{
ray = new Ray2D(transform.position, transform.up);
lineRenderer.positionCount = 1;
lineRenderer.SetPosition(0, transform.position);
float remainingLength = maxLength;
for (int i = 0; i < reflections; i++)
{
hit = Physics2D.Raycast(ray.origin, ray.direction, remainingLength, layerMask);
if (hit)
{
lineRenderer.positionCount += 1;
lineRenderer.SetPosition(lineRenderer.positionCount - 1, hit.point);
remainingLength -= Vector2.Distance(ray.origin, hit.point);
ray = new Ray2D(hit.point, Vector2.Reflect(ray.direction, hit.normal));
if (hit.collider.tag != "Reflect")
break;
}
else
{
lineRenderer.positionCount += 1;
lineRenderer.SetPosition(lineRenderer.positionCount - 1, ray.origin + ray.direction * remainingLength);
}
}
}
PREVIEW
When going to the right.
When going to left.
Sometimes it flickers too, I don't have any idea how this happens, I thought it was because order layer I have changed this but nothing happen.
In regard to the flickering, this is occuring due to a clipping issue with the collided object and the line itself.
Inside of the condition:
if (hit)
Adjust the code to be the following:
// Get the reflected vector of the raycast.
Vector2 updatedDirection = Vector2.Reflect(ray.direction, hit.normal);
// Create new Ray object & set origin to be 0.01f away from hitpoint so the line is not colliding with the gameobject collider.
ray = new Ray2D(hit.point + updatedDirection * 0.01f, updatedDirection);
You can find out more from these links:
https://answers.unity.com/questions/1602542/line-renderer-flickering-when-updated-in-runtime.html
https://answers.unity.com/questions/1690411/help-with-reflecting-in-2d.html?childToView=1690554#comment-1690554
As for the reason the line is not reflecting on the right wall, this is more than likely due to the gameObjects tag not being set to "Reflect". You are only creating a new reflected line when colliding with an object with that tag. Double check that the right walls gameObject has the tag "Reflect" set in the inspector.

How to make a smooth crosshair in Unity3D?

In Unity 3D I'd like to create a crosshair for my top-down 2D-shooter that gradually moves to its target whenever the player has the same x-position as the target.
The problem is that I want a smooth animation when the crosshair moves to the target. I have included a small gif from another game that shows a crosshair I'd like to achieve. Have a look at it:
Crosshair video
I tried to do that with the following script but failed - the crosshair jumps forth and back when the enemies appear. It doesn't look so smooth like in the video I mentioned above.
The following script is attached to the player:
[SerializeField]
private GameObject crosshairGO;
[SerializeField]
private float speedCrosshair = 100.0f;
private Rigidbody2D crosshairRB;
private bool crosshairBegin = true;
void Start () {
crosshairRB = crosshairGO.GetComponent<Rigidbody2D>();
crosshairBegin = true;
}
void FixedUpdate() {
//Cast a ray straight up from the player
float _size = 12f;
Vector2 _direction = this.transform.up;
RaycastHit2D _hit = Physics2D.Raycast(this.transform.position, _direction, _size);
if (_hit.collider != null && _hit.collider.tag == "EnemyShipTag") {
// We touched something!
Debug.Log("we touched the enemy");
Vector2 _direction2 = (_hit.collider.gameObject.transform.position - crosshairGO.transform.position).normalized;
crosshairRB.velocity = new Vector2(this.transform.position.x, _direction2.y * speedCrosshair);
crosshairBegin = false;
} else {
// Nothing hit
Debug.Log("nothing hit");
crosshairRB.velocity = Vector2.zero;
Vector2 _pos2 = new Vector2(this.transform.position.x, 4.5f);
if (crosshairBegin) crosshairGO.transform.position = _pos2;
}
}
I think you need create a new variable call Speed translation
with
speed = distance from cross hair to enemy position / time (here is Time.fixedDeltaTime);
then multiply speed with velocity, the cross hair will move to enmey positsion in one frame.
but you can adjust speed by mitiply it with some float > 0 and < 1;

How to move objects to the z and y coordinates of the mouse in Unity 3D

I'm trying to make the orange box follow my mouse. But with my current script, it only goes about a quarter of a unit towards the direction of my mouse, then stops. I am completely stuck & lost
using UnityEngine.EventSystems;
using UnityEngine;
public class drag : MonoBehaviour
{
private void Update()
{
Vector2 mousePos = Input.mousePosition;
Vector3 worldPos = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, Camera.main.nearClipPlane));
transform.position = new Vector3(transform.position.x, worldPos.y, worldPos.z);
}
}
Any help? This is for a game jam, I've got around 48 more hours to finish. Thanks!
Here you go:
private void Update()
{
// Get the mouse position
Vector3 mousePos = Input.mousePosition;
// Set the z component of the mouse position to the absolute distance between the camera's z and the object's z.
mousePos.z = Mathf.Abs(Camera.main.transform.position.z - transform.position.z);
// Determine the world position of the mouse pointer
Vector3 worldPos = Camera.main.ScreenToWorldPoint(mousePos);
// Update the position of the object
transform.position = worldPos;
}

Move the camera only until a certain position

https://scontent.fmgf1-2.fna.fbcdn.net/v/t34.0-12/15870843_1543174992374352_1359602831_n.gif?oh=dc048c9e04617007c5e82379fd5a9c1a&oe=586CC623
Can you see the blue area in this gif? I want block the camera when the player go more to left, to not see the blue area. This is the code that I'm using to move the camera:
public class configuracoesDaCamera : MonoBehaviour {
Vector3 hit_position = Vector3.zero;
Vector3 current_position = Vector3.zero;
Vector3 camera_position = Vector3.zero;
float z = 0.0f;
public static bool bDedoNoHud;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
hit_position = Input.mousePosition;
camera_position = transform.position;
}
if (Input.GetMouseButton(0))
{
current_position = Input.mousePosition;
LeftMouseDrag();
}
Debug.Log("bDedoNoHud" + bDedoNoHud);
}
void LeftMouseDrag()
{
if (!bDedoNoHud)
{
// From the Unity3D docs: "The z position is in world units from the camera." In my case I'm using the y-axis as height
// with my camera facing back down the y-axis. You can ignore this when the camera is orthograhic.
current_position.z = hit_position.z = camera_position.y;
// Get direction of movement. (Note: Don't normalize, the magnitude of change is going to be Vector3.Distance(current_position-hit_position)
// anyways.
Vector3 direction = Camera.main.ScreenToWorldPoint(current_position) - Camera.main.ScreenToWorldPoint(hit_position);
// Invert direction to that terrain appears to move with the mouse.
direction = direction * -1;
Vector3 position = camera_position + direction;
transform.position = position;
}
}
}
You mean setting up boundaries?
This should help you
Put it in the update()

Mouse input and z-axis

void OnMouseDrag() {
float distance = transform.position.z - Camera.main.transform.position.z;
Vector3 pos = Input.mousePosition;
pos.z = distance;
Vector3 mousePosition = new Vector3(pos.x, pos.y, pos.z);
Vector3 objPosition = Camera.main.ScreenToWorldPoint(mousePosition);
transform.position = objPosition;
}
This is the code snippet help me to move the object on mouse drag. It is moving object on mouse drag in x axis while z axis movement is not working correctly using mouse. I basically want to move the object on x and z-Axis using mouse Input.
What is wrong how can i get z position from the mouse input in order to move the object on z axis correctly.
When you casting ray to your object it is being calculated multiple times so it returns your ball position when its not being move a real deal you can try something like this
void OnMouseDrag() {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(ray.origin, ray.direction * 10, Color.yellow);
Debug.Log(ray);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Camera.main.farClipPlane))
{
if (hit.transform.gameObject.name == "CameraElasticPoint")
{
return;
}
else{
transform.position = new Vector3(hit.point.x,hit.transform.position.y+1, hit.point.z);
hitPoint = Input.mousePosition;
}
}
}
what it will do it will ignore your objects and works only on other hit info which would be your floor or any other surface you are trying to drag your object along and it will drag your object on X and Z axis taking the Y position of the Floor so it will always remain on top of the floor or any other surface collider on
let me know if it works
Good day
I would recommend going through the Unity Tutorial here:
http://unity3d.com/learn/tutorials/projects/survival-shooter-project
It might give you some ideas on how to solve the problem of x/z plane movement with the mouse.
No. screenpointtoray is very unnecessary here, you just need to say that pos.z is equal to pos.x....
like so...
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - dragOrigin);
pos.z = pos.x;
Vector3 move = new Vector3(0, pos.y * dragSpeed, pos.z * -dragSpeed);
always a pleasure x

Categories