Raycast can't find tagged gameobject - unity3d

My Raycastrotates around the player and scans the 2D-Area. It should recognize another Gameobject, which is tagged as Pick Up, but found is always false.
using UnityEngine;
using System.Collections;
public class Findway : MonoBehaviour {
public GameObject Player;
// Use this for initialization
void Start () {
transform.position = Player.transform.position;
}
RaycastHit hit;
float[] distance = new float[360];
int moveAngle = 0;
bool found = false;
// Update is called once per frame
void Update () {
transform.position = Player.transform.position;
for (int iii = 0; iii < 360; iii++)
{
Vector3 rayway = new Vector3 (Mathf.Cos(180 * iii / Mathf.PI), 0, Mathf.Sin(180 * iii / Mathf.PI));
if (Physics.Raycast (transform.position, rayway, out hit, 100f))
{
distance [iii] = hit.distance;
//Debug.Log(hit.collider.gameObject);
//Debug.DrawRay(transform.position, transform.forward, Color.green);
if (hit.collider.CompareTag ("Pick Up"))
{
moveAngle = iii;
found = true;
}
}
}
}
}

Use your ray cast out of the for loop , a good cpu will not take long to run the iteration till 360 and using it in update will cause it to run infinite times causing more problems, always use divide and conquer , minimize the code , remove everything and just run the ray to check if its working without any rotation , then apply rotation ,do tell if it worked .Double Check if there is a object tagged as "Pick Up" . Also never use a for loop in update without an explicit condition to stop it like a bool otherwise it keeps on running .

Related

How do I add a jumping delay to unity 2D character controllers?

Here is my character controller code.
public float speed;
float Velocity;
public float jump;
void Update ()
{
Velocity = 0;
if (Input.GetKey (KeyCode.LeftArrow) || Input.GetKey (KeyCode.A))
{
Velocity = -speed;
}
if (Input.GetKey (KeyCode.RightArrow) || Input.GetKey (KeyCode.D))
{
Velocity = speed;
}
if (Input.GetKey (KeyCode.UpArrow) || Input.GetKey("space") || Input.GetKey (KeyCode.W))
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (GetComponent<Rigidbody2D> ().velocity.x,
jump);
}
GetComponent<Rigidbody2D> ().velocity = new Vector2 (moveVelocity, GetComponent<Rigidbody2D>
().velocity.y);
}
}
This is a very simple movement code
here is my cam follow code i got from Brackeys
I am having an infinte jump problem with the code and i do not know what to do to fix it
I do not know the correct syntax yet to stop it.
I am using Unity 2019.4.2f1 and VScode 2020.
Im not sure if adding what versions I use will help
but I am always getting compiler errors saying that stuff does not exist in the current context but i do not know anything else that does exist in the current context that will work.
void Update()
{
transform.position = playerPos.position + offset;
}
To fix infinite jump, use Input.GetKeyDown(KeyCode.UpArrow) instead of Input.GetKey(KeyCode.UpArrow). The GetKey function is for checking when a key is held down. the GetKeyDown function is for getting the first time the key is pressed.

AI returning to original position

I want my enemy to move back to starting position. He follows me until I get out of his range and then he just stops.
Also i want my skeleton to stop for like 5 sec, and then go back to starting point, any ideas ? I never did anything involving time, exept stopping it.
Here is my script for enemy:
Also here is a screenshoot of inspector on the skeleton: enemy
Here is my script for enemy:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class chase : MonoBehaviour
{
public Transform player;
private Animator anim;
public float LookRadius = 15f;
public Transform enemyStartPos;
// Use this for initialization
void Start()
{
anim = GetComponent<Animator>();
this.enemyStartPos.position = this.transform.position;
}
// Update is called once per frame
void Update()
{
if (!PauseMenu.GameIsPaused)
{
if (Vector3.Distance(player.position, this.transform.position) < 15)
{
Vector3 direction = player.position - this.transform.position;
direction.y = 0;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation, Quaternion.LookRotation(direction), 0.1f);
anim.SetBool("isIdle", false);
if (direction.magnitude > 3)
{
this.transform.Translate(0, 0, 0.05f);
anim.SetBool("isWalking", true);
anim.SetBool("isAttacking", false);
}
else
{
anim.SetBool("isAttacking", true);
anim.SetBool("isWalking", false);
}
}
else
{
if (Vector3.Distance(this.enemyStartPos.position, this.transform.position) >1)
{
Vector3 direction = this.enemyStartPos.position - this.transform.position;
direction.y = 0;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation, Quaternion.LookRotation(direction), 0.1f);
anim.SetBool("isIdle", false);
if (direction.magnitude > 1)
{
this.transform.Translate(0, 0, 0.05f);
anim.SetBool("isWalking", true);
anim.SetBool("isAttacking", false);
}
}
else
anim.SetBool("isIdle", true);
anim.SetBool("isAttacking", false);
anim.SetBool("isWalking", false);
}
}
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, LookRadius);
}
}
Before you try to "code" this, think about it in terms of your program design. You have designed and implemented behavior that says "if the bot's position is within X units of the player's position, turn the bot and move it toward the player."
What you describe wanting to do next can be thought of in the same way (which should lead to similar code).. "else, if the bot's position is NOT within X units of the player's position, turn the bot and move it toward [origin]." Note, this means you need to define what [origin] is for the bot. Point being, it makes no difference in the code whether you are moving toward a player or some arbitrary fixed point. The code to move one transform toward another transform is the same.
For "wandering" it's essentially the same thought process: If bot is within X units of [origin] and not following player, pick a random direction and move that way. (better yet, pick a random direction and move that way for some amount of time so your bot doesn't just jitter around origin).

Unity navmesh. follow + stop certain distance away from target

Hi so what im trying to create is the player can right click on an enemy and he will follow at a certain distance. which is working fine. but what i want it to also do is stop at that distance too. currently if the enemy stops he will try and go to its exact position instead of stopping a little bit away this is what i have currently.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Attacking : MonoBehaviour {
NavMeshAgent agent;
Transform target;
public float distance;
public float followDistance;
// Use this for initialization
void Start () {
agent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButton(0))
{
target = null;
}
if (Input.GetMouseButton(1))
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100))
{
if (hit.collider.gameObject.tag == "enemy" || hit.collider.gameObject.tag == "Player")
{
target = hit.collider.transform;
}
}
}
if(target != null)
{
distance = Vector3.Distance(transform.position, target.position);
if (followDistance <= distance)
agent.destination = target.position;
}
}
}
Attach a script to your enemy and give it a certain radius ,say 3f.
public float radius=3f;
for better understanding and visual aid use OnDrawGizmosSelected() (on your enemy script).
void OnDrawGizmosSelected ()
{
Gizmos.color=Color.yellow;
Gizmos.DrawWireSphere(transform.position,radius);
}
Now,on your player script use agent.StoppingDistance() as:
if(target != null)
{
distance = Vector3.Distance(transform.position, target.position);
if (followDistance <= distance){
agent.destination = target.position;
agent.StoppingDistance=target.radius;
}
}
Note:you will have to change target from transform to an instance of your player

Incorrect text on screen

Hi I'm new to this unity and I'm making a 2d game the problem.I'm facing is displaying the right text in the screen , e.g I have a score count for keeping track of score and then I'm displaying this text through count.text , HOWEVER the problem is that when the game starts the text on screen displays "0", score is 0 as well, then I shoot an apple and the score becomes 1 as well as the count.text also becomes 1 however the text is still 0 on the screen, when I shoot another arrow the score and count.text shows value of 2 however on the screen it shows 1 and so on. I followed unity tutorial of roll the ball. here is my code
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class arrowcounttutorial : MonoBehaviour {
public GameObject Arrow;
public GameObject apple;
public int score = 0;
public Text count;
// Use this for initialization
void Start () {
this.gameObject.GetComponent<Rigidbody2D> ().AddForce (transform.right*1500.0f);
//score = 0;
//showcounttext ();
count.text = score.ToString ();
}
// Update is called once per frame
void Update () {
Vector3 diff = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
diff.Normalize();
float rot_z = Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rot_z - 0);
if (Input.GetMouseButtonUp (0)) {
GameObject bullet_new;
bullet_new = Instantiate (Arrow,new Vector2 (-0.23f, -3.78f), Quaternion.identity) as GameObject;
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition),Vector2.zero);
if (hit.collider!= null ) {
LeanTween.move(bullet_new, hit.collider.transform.localPosition, 1);
if(hit.collider.tag == "fruit")
{
score++;
//showcounttext();
count.text = score.ToString ();
print(count.text);
Destroy(hit.collider.gameObject,1);
Destroy(bullet_new,1);
}
}
}
}
/*
void showcounttext(){
count.text = score.ToString ();
}
*/
}
Also if I initialize the score in void start the text remains 0 through out the level even if the score and count.text are 1,2,3,4,5 so on. What can I do?
UPDATE
I don't know how it worked but I called an invoke function Invoke ("showcounttext",1); and it worked. I won't delete the question in case someone else have this same problem :)
I see your answer, good that it is fixed but it is not the best solution.
Prior to Unity3D version 5.3.1p3 this engine had problems with updating canvases, and sometimes the UI content was disapearing. You didnt tell version you use, but I am almost sure in this case it would help calling
Canvas.ForceUpdateCanvases ();
In your code it should look like that:
if(hit.collider.tag == "fruit")
{
score++;
//showcounttext();
count.text = score.ToString ();
print(count.text);
Destroy(hit.collider.gameObject,1);
Destroy(bullet_new,1);
Canvas.ForceUpdateCanvases ();
}
Try this, or upgrade Unity3D.

Unity - Infinite sprite spawner stops spawning at a high speed

i wrote a script for my 2D car game for an infinite track. So i got a "killer" behind my car, that destroys all ground objects coming out the screen on the left and on the right i have a spawner that spawns all my blocky sprites in it and it works pretty good.
Here is my update function:
void Update()
{
if(Mathf.Round(this.transform.position.x) == limit)
{
//Debug.Log("Limit reached");
limit += 10;
Spawn();
}
}
I attached the script to my camera and i have a start limit set to 160 (because i already got 15 10x10 sprites as start). Everytime my spawner passes the x-axis-limit it spawns a new sprite at this position and sets the next limit 10 higher. This works good if I don't drive too fast. Because then it stops spawning and the world is cut off. When I drive back to get my spawner back into the already spawned area and drive slowly again to it, it works again. I believe the method is just to inefficient to spawn fast enough so I maybe need another style of doing it.
For the understanding here the rest of the script:
using UnityEngine;
using System.Collections;
public class Spawner : MonoBehaviour
{
public GameObject[] obj;
private int limit = 160;
public int yAxisValue = -1;
public bool isOnlyDirt;
private ArrayList rotationValues = new ArrayList();
void Start()
{
//Spawn ();
int value = 0;
for(int i = 0; i < 4; i++)
{
rotationValues.Add(value);
//Debug.Log(rotationValues[i]);
value += 90;
}
}
void Spawn()
{
Vector3 pos = new Vector3 (Mathf.Round(transform.position.x), yAxisValue, transform.position.z);
Quaternion rotation = new Quaternion (0, 0, 0, 0);
if(isOnlyDirt)
{
int zRot = (int)rotationValues[Random.Range(0, rotationValues.Count - 1)];
//Debug.Log(zRot);
rotation = new Quaternion(0, 0, zRot, 0);
}
var SpawnedGround = Instantiate(obj[Random.Range(0, obj.GetLength(0))], pos, rotation);
(SpawnedGround as GameObject).gameObject.tag = "Gro
I also have a one-liner to move my spawner in front of my car so it can spawn things:
public float yCoord;
void Start ()
{
this.transform.position = new Vector3 (transform.position.x + 160, -yCoord, transform.position.z);
}
I parented it so i just have to write it in the start function.
Any ideas to improve this one?
Thanks
Sorry can't post as comments. You should try
if(Mathf.Round(this.transform.position.x) >= limit)
instead of
if(Mathf.Round(this.transform.position.x) == limit)
I think the floating point precision is skipping the checking.