Draw line between two game objects using linerenderer and raycast - c#

What I'm trying to do is draw line between two gameobjects I'm using ray distance and line renderer but the line is too long. Below is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DrawLineTest : MonoBehaviour
{
RaycastHit hit;
public LineRenderer lineRender;
private void Awake()
{
lineRender = GetComponent<LineRenderer>();
}
void Start()
{
Ray ray = new Ray(transform.position, Vector3.down);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
lineRender.enabled = true;
lineRender.SetPosition(0, transform.position);
lineRender.SetPosition(1, Vector3.down * hit.distance);
}
}
}
}

The second point is
lineRender.SetPosition(1, transform.position + Vector3.down * hit.distance);
or
lineRender.SetPosition(1, ray.GetPoint(hit.distance));
or more succinct
lineRender.SetPosition(1, hit.point);

Related

Not understanding why raycast code isnt working

Here is the Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RaycastControl : MonoBehaviour
{
LineRenderer line;
private Vector3 zeros;
public LayerMask EnemyLayer;
// Start is called before the first frame update
void Start()
{
line = GetComponent<LineRenderer>();
zeros = new Vector3(0f, 0f, 0f);
}
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Debug.Log("Detected the click");
Vector3 mouse = mouseToWorld(Input.mousePosition);
Ray ray = new Ray(zeros, mouse);
RaycastHit hitData;
if (Physics.Raycast(ray, 10000, EnemyLayer))
{
Vector3[] linePos = new Vector3[] { transform.position, mouse };
line.SetPositions(linePos);
Debug.Log("You've hit a Zomboid!");
}
}
}
public Vector3 mouseToWorld(Vector3 mousePos)
{
mousePos = Input.mousePosition;
mousePos.z = Camera.main.nearClipPlane;
Vector3 mouse = Camera.main.ScreenToWorldPoint(mousePos);
mouse.z = 0f;
return mouse;
}
}
Note: I'm using Unity2d
I'm trying to use 0,0,0 and the location of my mouse to cast a ray starting from 0,0,0 and running through the mouse location on to the specified max distance in if(physics.Raycast(ray,maxDistance,EnemyLayer)). this, however, does not work. When I click on or behind the "Zombie" object I've created, I dont get a raycast hit detected.
I've been sure to make sure that the layer mask set in this script is the same one set in the Zombie object. My Debug.Log("You've made it this far!"); line activates so I know the Script is in the scene and is being read, but the Physics.Raycast(ray,10000,EnemyLayer)) NEVER returns true, and we know this because Debug.Log("You've hit a Zomboid!") never shows up in console.
Note: The object this script is attached to, Center, sits at 0,0,0. its transform.position = 0,0,0
Your help is greatly appreciated.
Physics and Physics2D are separate in Unity and don't interact with each other.
Physics2D.Raycast() belongs to Physics2D and only responds to Physics2D (BoxCollider2D, CircleCollider2D, PolygonCollider2D, etc.)
Physics.Raycast() belongs to Physics and only responds to Physics (BoxCollider, SphereCollider, MeshCollider, etc.)
You are using Physics.Raycast() when you should be using Physics2D.Raycast().
This is how you would do it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RaycastControl : MonoBehaviour
{
LineRenderer line;
//private Vector3 zeros;
public LayerMask EnemyLayer;
// Start is called before the first frame update
void Start()
{
line = GetComponent<LineRenderer>();
//zeros = new Vector3(0f, 0f, 0f); not necessary this is the same as Vector3.zero
}
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Debug.Log("Detected the click");
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hit)
{
Vector3[] linePos = new Vector3[] { transform.position, hit.point};
line.SetPositions(linePos);
Debug.Log("You've hit a Zomboid!");
}
}
}
}```

how to remove inertia unity3d

I have a ball that jumps up a ladder, but when the jump ends, the ball still moves a short distance. It used to travel long distances and I just set freezeRotation = true, but the inertia still remained.
I would be glad to any advice. Here is my code
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class ballcontroller : MonoBehaviour
{
//public int speed = 3;
public int jumpForce;
public bool IsGround;
private Rigidbody rb;
private void Start()
{
rb = GetComponent<Rigidbody>();
}
private void Update()
{
//float Vm = Input.GetAxis("Vertical");
//float Hm = Input.GetAxis("Horizontal");
//Vector3 V3M = new Vector3(Hm, 0, Vm);
//rb.AddForce(V3M * speed);
Jump();
}
public void Jump()
{
Ray ray = new Ray(gameObject.transform.position, Vector3.down);
RaycastHit rh;
if (Physics.Raycast(ray, out rh, 0.5f))
{
IsGround = true;
}
else
{
IsGround = false;
}
if (Input.GetKeyDown(KeyCode.Space) && IsGround)
{
rb.AddForce(Vector3.one * jumpForce);
rb.freezeRotation = true;
}
}
}
You can directly manipulate the velocity of your rigidbody using Rigidbody.velocity and Rigidbory.angularVelocity.
You could set it to Vector3.zero (or decrease it slowly to avoid hard freezing) after you hit the ground.

Unity fix NavMeshAgent jerky movements?

Record of the problem
https://youtu.be/BpzHQkVQz5A
Explaining my problem
I'm programming a mobile game using Unity3D Engine. For my player movement, I'm using NavMeshAgent because it's for me the easiest and most efficient way to do it. But when I hit the play button and ask my player to move, the movements are jerky and it's not pleasant to see at all.
Do you have any idea to fix this problem ?!
Thank you in advance for your answers ! ^^
My code
This is my code :
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Player : MonoBehaviour
{
NavMeshAgent agent;
Touch touch;
RaycastHit hit;
Ray ray;
// START FUNCTION
private void Start()
{
agent = GetComponent<NavMeshAgent>();
}
// UPDATE FUNCTION
private void Update()
{
// TOUCH DETECTION
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
// A FINGER TOUCHED THE SCREEN
if (touch.phase == TouchPhase.Began)
{
// RETURN X, Y AND Z WORLD POS OF THE TOUCH SCREEN POS
ray = Camera.main.ScreenPointToRay(touch.position);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
// MOVING PLAYER TO THE HIT POS
Vector3 hitVec = new Vector3(hit.point.x, hit.point.y + (GetComponent<Collider>().bounds.size.y / 2), hit.point.z);
agent.SetDestination(hitVec);
}
}
}
}
// SAME CODE USING MOUSE BUTTON
#if UNITY_EDITOR
if (Input.GetMouseButton(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
Vector3 hitVec = new Vector3(hit.point.x, hit.point.y + (GetComponent<Collider>().bounds.size.y / 2), hit.point.z);
agent.SetDestination(hitVec);
}
}
}
#endif
}
}
CameraFollow.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// BRACKEYS CAMERA FOLLOW SCRIPT WITHOUT THE LOOKAT METHODE
public class CameraFollow : MonoBehaviour
{
public Transform target;
public float smoothSpeed = 0.2f;
public Vector3 offset;
void FixedUpdate()
{
Vector3 desiredPosition = target.position + offset;
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
transform.position = smoothedPosition;
}
}
The problem isn't the navmesh controller but the camera follow script.
One thing you could try is to move the camera position using only the desiredPosition or use Vector3.SmoothDamp:
private Vector3 velocity;
void LateUpdate(){
...
Vector3 desiredPosition = target.position + offset;
Vector3 smoothedPosition = Vector3.SmoothDamp(transform.position, desiredPosition, ref velocity, smoothSpeed);
transform.position = smoothedPosition;
}
Also this is explained in a pinned comment on the Brackeys video

Android Drag Sprite code Unity 5

I'm new to Unity and have been following a tutorial on how to make a Captain Blaster 2D game, however I want to convert it to Android, I want to make the player controllable by dragging him across the screen with one finger and don't understand what's wrong with my code, anything helps, thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ShipControl : MonoBehaviour {
public float playerSpeed = 10f;
public GameControl gameController;
public GameObject bulletPrefab;
public float reloadTime = 1f;
private float elapsedTime = 0;
void Update()
{
elapsedTime += Time.deltaTime;
if (Input.touchCount >= 1)
{
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay (touch.position);
RaycastHit hit;
if (Physics.Raycast (ray, out hit, 100)) {
}
}
if (elapsedTime > reloadTime)
{
Vector3 spawnPos = transform.position;
spawnPos += new Vector3 (0, 1.2f, 0);
Instantiate (bulletPrefab, spawnPos, Quaternion.identity);
elapsedTime = 0f;
}
}
}
void OnTriggerEnter2D(Collider2D other)
{
gameController.PlayerDied ();
}
}
What I would do is add a bool called "dragging" and after you check if Raycast hit anything you also check if hit object is the player GameObject.
If it is then as long as user is not releasing the touch - make player's rigidbody move towards the touch position (so if there are any obstacles it simply doesn't move right through them).
Code would probably look like this (you should also add some timer to check if player released touch and set dragging bool to false):
public float playerSpeed = 10f;
public GameControl gameController;
public GameObject bulletPrefab;
public float reloadTime = 1f;
private float elapsedTime = 0;
private bool dragging = false;
void Update()
{
if (Input.touchCount >= 1)
{
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay (touch.position);
RaycastHit hit;
if (Physics.Raycast (ray, out hit, 100))
{
if(hit.collider.tag == "Player") // check if hit collider has Player tag
{
dragging = true;
}
}
if(dragging)
{
//First rotate the player towards the touch (should do some checks if it's not too close so it doesn't glitch out)
Vector3 _dir = Camera.main.ScreenToWorldPoint(touch.position) - transform.position;
_dir.Normalize();
float _rotZ = Mathf.Atan2(_dir.y, _dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, _rotZ - 90);
//Move towards the touch
transform.GetComponent<Rigidbody>().AddRelativeForce(direction.normalized * playerSpeed, ForceMode.Force);
}
}
}
}

Unity 3D Door Script Angle Transformation

i write the following code for open and close doors:
using UnityEngine;
using System.Collections;
public class LittleDoorScript : MonoBehaviour
{
private bool doorOpen = false;
private Ray ray;
private RaycastHit hit;
private float distance = 5.0f;
public GameObject door;
private void Update()
{
if (Input.GetKeyDown("e"))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, distance))
{
if(hit.collider.gameObject.name == door.name)
{
if (!doorOpen)
{
Quaternion targetRotation = Quaternion.Euler(0.0f, 90.0f, 0.0f);
hit.transform.localRotation = Quaternion.Slerp(transform.localRotation, targetRotation, 2.0f);
doorOpen = true;
}
else
{
Quaternion targetRotation2 = Quaternion.Euler(0.0f, 0.0f, 0.0f);
hit.transform.localRotation = Quaternion.Slerp(transform.localRotation, targetRotation2, 2.0f);
doorOpen = false;
}
}
}
}
}
}
the problem is the door not open in the right angle and if i close the door the not go back in the start position.
Maybe somebosy have an idea?
Try changing the angle to -90, it always happens to me.
Quaternion targetRotation = Quaternion.Euler(0.0f, -90.0f, 0.0f);
the second one:
Quaternion targetRotation2 = Quaternion.Euler(0.0f, 90.0f, 0.0f);

Categories