Shoot out several Raycasts to check for an object - c#

i am working on an enemy for my game that follows you until it doesnt see you anymore.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class pathfindingPlayer : MonoBehaviour
{
RaycastHit hit;
NavMeshAgent _navMeshAgent;
void Awake() => _navMeshAgent = GetComponent<NavMeshAgent>();
public bool seen;
public float noticeDistance = 7f;
void Update()
{
Debug.DrawRay(transform.position, transform.forward * noticeDistance, Color.red);
Ray PlayerRay = new Ray(transform.position, Vector3.back);
if(Physics.Raycast(PlayerRay, out RaycastHit hitInfo, noticeDistance))
{
if (hitInfo.collider.CompareTag("Player"))
{
Vector3 SeenPlayer = hitInfo.point;
_navMeshAgent.SetDestination(SeenPlayer);
}
}
}
}
Now the problem is that there is only one Raycast being shot out. Therefore the enemy only runs in one direction. Is there a way to add multiple raycasts to this or do i need to rewrite the code? Thanks in advance

You can make a function that makes raycasts and call it every x seconds, but for what you want to achieve i would try putting a circle collider on the enemy with the radius of how far the enemy can see and make sure to set the collider as trigger, then make it go towards the player if the player triggers the collider

Related

Unity how to affect variable from other classes with raycast. By using scripting and visual scripting bolt

I need to blind an enemy ai with the use of raycast.
When the raycast collides with the enemy, the boolean of the enemy isblinded must be set to true.
I have refrenced the enemy gameobject, but the console log gives me this error.
NullRefrenceException: Object refrence not set to an instance of an object Raycast.Update() (at Assets/Scripts/Raycast.cs.23).
The assignment is to detect if the raycast hits the enemy and transfer the state with visual scipting.
This is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Raycast : MonoBehaviour
{
[SerializeField] LayerMask enemyLayer;
RaycastHit hitinfo;
public GameObject enemy;
// Start is called before the first frame update
void Update()
{
Ray ray = new Ray(transform.position, transform.TransformDirection(Vector3.forward));
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 20, Color.red);
if (Physics.Raycast(ray, out hitinfo, 100, enemyLayer))
{
Debug.Log("Hit");
Debug.Log(hitinfo.collider.gameObject.name);
//enemy is blinded is true
enemy.GetComponent<Enemy>().isBlinded = true;
Debug.Log(enemy.GetComponent<Enemy>().isBlinded);
}
else
{
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 20, Color.green);
}
}
}
I tried using the Enemy enemyscript class, but that doesn't let me add the enemy object in the inspector.
It looks like you're getting a reference to the GameObject itself rather than the script/component on the GameObject.
Try:
private EnemyScript enemyScript;
...
if (Physics.Raycast(ray, out hitinfo, 100, enemyLayer))
{
Debug.Log("Hit");
Debug.Log(hitinfo.collider.gameObject.name);
//enemy is blinded is true
enemyScript = hitinfo.collider.gameObject.GetComponent<EnemyScript>();
enemyScript = true;
Debug.Log(enemyScript.isBlinded);
}

Unity FollowMousePos

I build my first game and want to Instantiate an object,
the player should be allowed to choose where to instantiate it. It should be on the ground(plane) and the object(cube) should follow the mousePos. That's where the problem occurs. I tried for hours now (at least 5) but can't figure it out. I tried raycast and screentoWorld stuff, but the object doesn't follow my mouse perfectly. The best i could get is, if i moved right, the cube moved right, same for all the other directions but it did not move the same speed as my mouse, so it was not at the same pos and i can't "OnMouseDown" it(except for the very middle of the screen) I use an Orthographic Camera, the speed the Cube is moving with the mouse seems to be dependent on my camera Size, but I want it to work in any size etc. Thanks for any help in advance.
This is my code:
using UnityEngine;
using System;
public class VorKasernenBau : MonoBehaviour
{
public static event Action<Vector3> onBuildBuilding;
public Camera cam;
public GameObject kasernePrefab;
private void Update()
{
moveMe();
}
private void OnMouseDown()
{
if (true/*if genug platz*/)
{
Instantiate(kasernePrefab, transform.position, Quaternion.identity, transform.parent);
if (onBuildBuilding != null)
onBuildBuilding.Invoke(transform.position);
Destroy(gameObject);
}
}
private void moveMe()
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.CompareTag("Ground"))
{
transform.position = hit.point + Vector3.up;
Debug.Log("test");
}
}
}
}
Update1:
The z Position seems to be okay, but the xPos isn't following perfectly.
I moved the object with another function. (cam.screentoworld and y value to 1) This problem is solved(even known i am not really happy with this solution), but another problem comes with it. if i move the screen in play mode (through drag and drop), the mousePos is not calculated right since the calculated mousepos isn't translated like the screen. Anyways have a great night and thanks for the help.
Vector3 pos = cam.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(pos.x,1,pos.z);

Collision Detection If Raycast Source Is inside A Collider

I am trying to cast a ray from inside source to Sphere.
my main camera position (0,0,0)
Sphere position (0,0,0) radius : 300
I want to know hit.position and hit.collider.gameobject
I am trying this below tutorial.
http://answers.unity3d.com/questions/129715/collision-detection-if-raycast-source-is-inside-a.html
Even if I tried tutorial, I can not see desirable result from console window.
(no Debug.Log result in my console window)
What should I have to do?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EyeTrackingPoint : MonoBehaviour
{
public float sphereRadius = 300; // position(0,0,0) radius 300
public GameObject screen3D; // sphere
public void Update()
{
Camera cam = Camera.main; // position(0,0,0)
RaycastHit hit;
Ray ray = new Ray(cam.transform.position,cam.transform.rotation * Vector3.forward * sphereRadius );
ray.direction = -ray.direction;
if (Physics.Raycast(ray,out hit)&&hit.collider.gameObject.Equals(screen3D))
{
Debug.Log(hit.point);
}
}
}
Thank you for reading.
Raycast in unity has to be conform to these things; Use a worldpoint from where the ray should originate. Use a direction for that ray. And u need to specifiy in which layer it is supposed to check. On top of that only objects with colliders can be hit, even if the gameobject is in the correct layer but doesn't have a active collider nothing will happen. Example ;
{
RaycastHit hit = Physics.Raycast(start, direction, 1000f, 1<<10);
}
The information of a successful raycast is saved in a RaycastHit;
The 1000f is a float value that limits the range of the raycast That way u can control how far it looks for an object.
If u do not specify the layermask in the raycast it will return the first object hit with any kind of active collider regardless in which layer it is.
Raycasts from inside colliders do NOT generate collisions.
if (Physics.Raycast(Vector3.zero, Vector3.up, 100))
Debug.Log("HIT");
"Hit" will never be written in console if a sphere is around the 0,0,0 world origin. When you move the sphere out , over and away from the origin, you will see it printed.
Those are impact in backfaces. You can enable it, though, enabling the checkbox in the Physics settings. See the documentation on this parameter on c# too: https://docs.unity3d.com/ScriptReference/Physics-queriesHitBackfaces.html

How do I make my player with a Rigidbody move with isKinematic checked?

My game is a topdown zombie shooter and whenever the zombies get to the player they bunch up underneath them, to the point where the player can just walk over the zombies. I noticed that when I check isKinematic on the Rigidbody the zombies cant push the player up to go underneath him, so they just run into him(which is what I want). Despite this I am then unable to move. How can i fix this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMoving1 : MonoBehaviour {
public float moveSpeed;
private Rigidbody myRigidbody;
private Vector3 moveInput;
private Vector3 moveVelocity;
private Camera mainCamera;
public GunController theGun;
void Start () {
myRigidbody = GetComponent <Rigidbody>();
mainCamera = FindObjectOfType<Camera>();
}
// Update is called once per frame
void Update () {
moveInput = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput * moveSpeed;
Ray cameraRay = mainCamera.ScreenPointToRay(Input.mousePosition);
Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
float rayLength;
if(groundPlane.Raycast(cameraRay,out rayLength))
{
Vector3 pointToLook = cameraRay.GetPoint(rayLength);
transform.LookAt(new Vector3(pointToLook.x,transform.position.y,pointToLook.z));
}
if (Input.GetMouseButtonDown(0))
theGun.isFiring = true;
if (Input.GetMouseButtonUp(0))
theGun.isFiring = false;
}
void FixedUpdate(){
myRigidbody.velocity = moveVelocity;
}
}
With isKinematic == true You can't change object position through rigidbody, You can only change transform.position.
I think it could be better, if You set isKinematic to false and add stopping distance to enemies, so they can't get too close to player.
Being that your player can no longer be effected by the physics engine, you'd have to manipulate the object's transform manually. Your script isn't ideally setup for it currently, but if I was to hack it into it and try to make it work it would look something like this:
(you can change it from fixedUpdate to update if you're no longer utilizing the physics engine)
void update(){
float x = Input.GetAxisRaw("Horizontal")* Time.Deltatime;
float z = Input.GetAxisRaw("Vertical") * Time.Deltatime;
transform.position = new Vector3(transform.position.x+x,0,transform.position.z+z);
Another way of doing this is to lock the position of Y for the player (assuming Y is the positive "up" direction). isKinimatic is best when you want to move the player or objects around yourself.
I would say upping the mass is better in this case, and you can keep isKinematic unchecked in this case then too. Also apply the lock for Y movement (again if it is the "up" direction from the plane)
Let me know what your solution is regardless, I've had some issues in the past as well with these types of events happening

2D Unity Enemy Chase/Evade script in C#

Okay so I've been fighting with this script for a couple days now. I've made progress in other aspects but I can't seem to get my enemies to properly chase the player character.
The script is supposed to have the enemies wander until an empty child 'eyes' sees the player. Then it should start chasing the player. Think pac-man. What it's doing right now is making one loop of it's wander cycle and then stopping and not seeing the player at all.
This is the code that I've got so far for that script -
using UnityEngine;
using System.Collections;
public class dudeFollow : MonoBehaviour {
Transform tr_Player;
float f_MoveSpeed = 3.0f;
private DudeMove moveScript;
public Transform eyes;
public float sightRange = 3f;
// Use this for initialization
void Start () {
tr_Player = GameObject.FindGameObjectWithTag("Player").transform;
moveScript = GetComponent<DudeMove>();
}
// Update is called once per frame
void Update () {
RaycastHit hit;
if (Physics.Raycast (eyes.transform.position,eyes.transform.forward, out hit,sightRange) && hit.collider.CompareTag ("Player")) {
transform.position += transform.forward * f_MoveSpeed * Time.deltaTime;
moveScript.enabled = false;
}
}
}
Any help or tips would be appreciated.
Because you have 2D game, what most likely happens is your enemy wonders away on z-axis as well, but because it's 2D, you can't see it. So switch to 3D mode in your main scene window and see if that's the case.
If it is, just reset z-axis to 0 on every frame and disable angular momentum :) I had this happen with 2D games.
void Update () {
RaycastHit hit;
if (Physics.Raycast (eyes.transform.position,eyes.transform.forward, out hit,sightRange) && hit.collider.CompareTag ("Player")) {
transform.position += transform.forward * f_MoveSpeed * Time.deltaTime;
moveScript.enabled = false;
}
transform.position.z = 0; // or something along those lines, I don't remember the syntax exactly.
}

Categories

Resources