Convert Raycast from 3D to 2D - c#

Hi im trying to convert a code that work on 3D project to get gameobject which i click on my mouse to work on 2D since im now doing a 2D project
public class SetTower : MonoBehaviour {
public int selected;
public GameObject[] towers;
public float[] prices;
public GameObject tile;
private Money moneyScript;
// Use this for initialization
void Start ()
{
moneyScript = GameObject.Find("GameLogic").GetComponent<Money>();
}
// Update is called once per frame
void Update ()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 20))
{
if(hit.transform.tag == "Tile")
{
tile = hit.transform.gameObject;
}
else
{
tile = null;
}
if (Input.GetMouseButtonDown(0) && tile != null)
{
TileTaken tileScript = tile.GetComponent<TileTaken>();
if(!tileScript.isTaken && moneyScript.money >= prices[selected])
{
moneyScript.money -= prices[selected];
Vector2 pos = new Vector2(tile.transform.position.x, tile.transform.position.y);
tileScript.tower = (GameObject)Instantiate(towers[selected], pos, Quaternion.identity);
tileScript.isTaken = true;
}
}
}
}
}

Replace Camera.main.ScreenPointToRay with Camera.main.ScreenToWorldPoint, Physics.Raycast with Physics2D.Raycast, and RaycastHit with RaycastHit2D. Make sure to also switch to 2D Colliders. For example, Box Collider should be replaced with Box Collider 2D.
public class SetTower : MonoBehaviour
{
public int selected;
public GameObject[] towers;
public float[] prices;
public GameObject tile;
private Money moneyScript;
// Use this for initialization
void Start()
{
moneyScript = GameObject.Find("GameLogic").GetComponent<Money>();
}
// Update is called once per frame
void Update()
{
Vector2 ray = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(ray, Vector2.zero, 20);
if (hit)
{
if (hit.transform.tag == "Tile")
{
tile = hit.transform.gameObject;
}
else
{
tile = null;
}
if (Input.GetMouseButtonDown(0) && tile != null)
{
TileTaken tileScript = tile.GetComponent<TileTaken>();
if (!tileScript.isTaken && moneyScript.money >= prices[selected])
{
//moneyScript.money -= prices[selected];
Vector2 pos = new Vector2(tile.transform.position.x, tile.transform.position.y);
//tileScript.tower = (GameObject)Instantiate(towers[selected], pos, Quaternion.identity);
//tileScript.isTaken = true;
}
}
}
}
}

Related

Why does my gun fire once upon loading in?

I have made a gun with multiple firing modes. Upon loading in the weapon (both through loading the scene and through switching to another gun and back to it) it will fire a single shot with sound and light. What is causing it to fire this one bullet and how do I stop the weapon from doing so?
I already tried to add a delay before it should be allowed to fire by making the 1 higher in start. I also tried to add more time to "timeBeforeShooting" in the Void auto section. Setting "shooting" to false and true instead of leaving it blank did not help either.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AutomaticGun1 : MonoBehaviour
{
public enum firingMode
{
auto = 1,
semi = 2,
burst = 3
}
[SerializeField] private firingMode currentFiringMode = firingMode.auto;
[SerializeField] private LayerMask enemyLayer;
[SerializeField] private float damage;
[SerializeField] private float fireRate;
private float timeBeforeShooting;
private bool shooting;
private int firingModeID = 1;
public Camera playerView;
public ParticleSystem muzzleFlash;
public AudioSource bang;
// Start is called before the first frame update
void Start()
{
timeBeforeShooting = 1 / fireRate;
playerView.GetComponent<Camera>();
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.V))
{
firingModeID++;
if(firingModeID > 3)
{
firingModeID = 1;
}
currentFiringMode = (firingMode)firingModeID;
Debug.Log(firingModeID);
}
switch(currentFiringMode)
{
case firingMode.auto:
auto();
break;
case firingMode.semi:
semi();
break;
case firingMode.burst:
burst();
break;
}
}
void auto()
{
if (Input.GetMouseButton(0))
{
if (timeBeforeShooting <= 0f)
{
muzzleFlash.Play();
bang.Play();
Ray gunRay = new Ray(playerView.transform.position, playerView.transform.forward);
if (Physics.Raycast(gunRay, out RaycastHit hitInfo, 100f, enemyLayer))
{
if (hitInfo.collider.gameObject.TryGetComponent(out enemy1 enemyHit))
{
enemyHit.SubtractHealth(damage);
Debug.Log(enemyHit.health);
}
}
timeBeforeShooting = 1 / fireRate;
}
else
{
timeBeforeShooting -= Time.deltaTime;
}
}
else
{
timeBeforeShooting = 0f;
}
}
void semi()
{
if (Input.GetMouseButtonDown(0))
{
if (timeBeforeShooting <= 0f)
{
muzzleFlash.Play();
bang.Play();
Ray gunRay = new Ray(playerView.transform.position, playerView.transform.forward);
if (Physics.Raycast(gunRay, out RaycastHit hitInfo, 100f, enemyLayer))
{
if (hitInfo.collider.gameObject.TryGetComponent(out enemy1 enemyHit))
{
enemyHit.SubtractHealth(damage);
Debug.Log(enemyHit.health);
}
}
}
}
}
void burst()
{
if (Input.GetMouseButtonDown(0) && !shooting)
{
StartCoroutine(burstShots(3));
shooting = true;
}
}
IEnumerator burstShots(int timesToShoot)
{
for (int timesShot = 1; timesShot <= timesToShoot; timesShot++)
{
muzzleFlash.Play();
bang.Play();
Ray gunRay = new Ray(playerView.transform.position, playerView.transform.forward);
if (Physics.Raycast(gunRay, out RaycastHit hitInfo, 100f, enemyLayer))
{
if (hitInfo.collider.gameObject.TryGetComponent(out enemy1 enemyHit))
{
enemyHit.SubtractHealth(damage);
Debug.Log(enemyHit.health);
}
}
yield return new WaitForSeconds(0.5f / fireRate);
}
shooting = false;
}
}

Instantiated object doesn't instantiate other object on the raycast

When the code starts I instantiate a Random amount of new raycasts (from 1 to 4) from the original Raycast:
public class MultipleRaycasts : MonoBehaviour
{
public GameObject Raycastobj;
private GameObject RCclone;
public int RandomSTRUNKnumber;
void Start()
{
Destroy(gameObject);
RandomSTRUNKnumber = Random.Range(1, 4);
for (int m = 0; m < RandomSTRUNKnumber; m++)
{
RCclone = Instantiate(Raycastobj);
}
}
}
After the button is clicked all the moving raycasts are stopping if they hit the object (I am not attaching this one), and instantiate the "RandomSTrunk" object on the other object:
public class PlayerRayINST : MonoBehaviour {
public Transform RandomSTrunk2;
public bool RCnn;
public bool RCCheck;
public void Update()
{
Debug.DrawRay(transform.position, transform.forward * 100f, Color.yellow);
RCnn = true;
RCCheck = true;
Ray ray1 = new Ray(transform.position, transform.forward);
RaycastHit hit1;
if (Physics.Raycast(ray1, out hit1))
{
if (hit1.collider.gameObject.GetComponent<SelectableTrunk>())
{
RCnn = false;
RCCheck = false;
}
else
{
RCnn = true;
RCCheck = true;
}
}
}
public void OnMouseDown()
{
Invoke("Addbranch", 0.5f);
}
void Addbranch()
{
Ray ray2 = new Ray(transform.position, transform.forward);
RaycastHit hit2;
if (Physics.Raycast(ray2, out hit2))
{
if (hit2.collider.gameObject.GetComponent<SelectableTrunk>())
{
Transform clone = Instantiate(RandomSTrunk2);
clone.position = hit2.point;
clone.LookAt(hit2.transform.position - hit2.transform.forward, hit2.normal);
}
}
}
}
My code somehow instantiates the "RandomSTrunk" only from the original Raycast. It ignores the instantiated earlier Raycasts and does not want to Instantiate the "RandomSTrunk" from the other raycasts.
However, if I put Update instead of OnMouseDown It will instantiate correctly but with millions of generated clones. I've just started learning unity, so please help me ;)

I'm creating a patrolling AI that aggros to the player and follows them in Unity 3D

I'm having trouble keeping this method running. It runs for 1 frame them shuts itself off. I am having trouble working out the logic to keep it running. Yes, the enemy does detect if the player is within a field of view, and it does stop when it collides with walls, it also stops detecting the player when they leave the fov.
I've tried changing around if statements, but it's overall very important that the code runs based on the player existing in the FOV collider. The problem is pretty specific, so I don't know what research to do.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(AudioSource))]
public class EnemyAI : MonoBehaviour
{
public float patrolSpeed, chaseSpeed, chaseWaitTime, patrolWaitTime, castRadius;
public Transform[] wayPoints, wayPOI;
public Transform player;
public Animation flinch, die;
public AudioClip grunt, callOut, death;
public LayerMask mask;
public PlayerCheck check;
private float chaseTimer, patrolTimer, wanderTimer;
private int destIndex, destInit, destStart, health;
private bool playerIn;
protected string aggro, resting, warned, sawPlayer;
protected bool patroling;
public bool aggress;
private NavMeshAgent agent;
private Transform playerLP;
private Vector3 startPos;
private Animator anim;
private AudioSource aud;
MeshCollider fieldOfView;
void Awake()
{
//patroling = true;
startPos = transform.position;
destInit = destIndex;
agent = GetComponent<NavMeshAgent>();
agent.autoRepath = true;
agent.autoBraking = true;
fieldOfView = transform.GetChild(0).GetComponent<MeshCollider>();
if (fieldOfView == null)
{
Debug.LogError("The first object MUST be FOV, otherwise the script will not work correctly. 1");
}
check = GameObject.FindObjectOfType<PlayerCheck>();
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
if (check == null)
{
check = GameObject.FindObjectOfType<PlayerCheck>();
}
playerIn = check.playerIn;
RaycastHit hit;
if (Physics.Linecast(transform.position, player.position, out hit, ~mask))
{
if (!playerIn)
{
Debug.DrawLine(transform.position, hit.point, Color.red);
}
else if (hit.collider.gameObject != null)
{
if (!hit.collider.CompareTag("Player"))
{
Debug.DrawLine(transform.position, hit.point, Color.blue);
return;
}
else
{
Debug.DrawLine(transform.position, hit.point, Color.green);
aggress = true;
}
}
}
if (aggress)
{
Aggro(sawPlayer);
}
if (patroling)
{
GoToNext();
}
}
void GoToNext()
{
patroling = true;
aggress = false;
if (wayPoints.Length == 0)
return;
if (playerIn)
return;
if (agent.remainingDistance < .7f)
{
agent.SetDestination(wayPoints[destIndex].position);
destIndex = (destIndex + 1) % wayPoints.Length;
}
}
void Aggro(string condition)
{
if (condition == sawPlayer)
{
Chase(player);
}
}
void Chase(Transform transform)
{
patroling = false;
if (playerIn)
{
agent.SetDestination(transform.position);
print("Chasing");
}
else
{
**Wander(sawPlayer, 15);**
print("Wander, please");
}
}
**void Wander(string condition, float time)**
{
patroling = false;
print(time);
wanderTimer += Time.deltaTime;
print("Wandering");
//this is where I'm having the most trouble, it will print wandering for 1 //frame then stop and go back to patroling
//once the player leaves the fov. I'm trying to figure out where the method //stops and why.
if (condition == sawPlayer)
{
if (wanderTimer >= time)
{
wanderTimer = 0;
if (!agent.pathPending && agent.remainingDistance < .5f)
{
GoToNext();
}
}
else
{
Vector3 vec;
vec = new Vector3(Random.Range(agent.destination.x - 10, agent.destination.x), Random.Range(agent.destination.y - 10, agent.destination.y), Random.Range(agent.destination.z - 10, agent.destination.z));
agent.destination = transform.InverseTransformDirection(vec);
if (agent.remainingDistance < .3f || wanderTimer > time)
{
GoToNext();
}
}
}
}
}

prefab does not work same as its origin

public class green : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "BLUE")
{
Destroy(other.gameObject);
gm.mylife -= 1;
}
}
}
public class gm : MonoBehaviour
{
public GameObject blue;
static public bool tr = false;
public Text life;
public static int mylife = 0;
void Start()
{
makebox();
}
void makebox()
{
StartCoroutine("timedelay");
}
IEnumerator timedelay()
{
yield return new WaitForSeconds(3f);
Debug.Log("sdfaDF");
GameObject br = Instantiate(blue, new Vector3(-6, -2, 0), Quaternion.identity) as GameObject;
makebox();
}
void Update()
{
life.text = (mylife.ToString());
}
}
I made a blue box which is destroyed when it meets something and has -1 score.
And it is made at (-2,2)position .
Then I made a prefab. But the prefab does not work as its origin. It is JUST created at the same position as its origin.
I want to make my prefab destroy and score -1 also.
How can i fix it ?
PLEASE HELP ME...
You are spawning the object at same position all the time:
GameObject br = Instantiate(blue, new Vector3(-6, -2, 0), Quaternion.identity) as GameObject;
Instead you should give a new position every time like this:
public Vector3 offSet = new Vector3(2,0,0);
Vector3 pos;
IEnumerator timedelay()
{
yield return new WaitForSeconds(3f);
Debug.Log("sdfaDF");
GameObject br = Instantiate(blue, pos, Quaternion.identity) as GameObject;
pos += offSet;
makebox();
}
GameObject blue = Instantiate(bluep);
blue.tag = "BLUE";
I solved by giving tag to the object at the script.

Unity2D: How to make spawn object gradually go faster after the player collects 10 points?

so I was wondering if there was a way to make a spawned object gradually moves/go faster after the player (you the user) collects 10 points. And faster when the player collects another 10 points and so on and so on?
This is my movement script attach to my objects that get spawned in:
public class Movement : MonoBehaviour
{
public static int movespeed = 20;
public Vector3 userDirection = Vector3.right;
public void Update()
{
transform.Translate(userDirection * movespeed * Time.deltaTime);
}
}
This is my score script attach to my player
public int Score;
public Text ScoreText;
void Start ()
{
Score = 0;
SetScoreText ();
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag ("Pick Up"))
{
other.gameObject.SetActive (false);
Score = Score + 1;
SetScoreText ();
}
}
void SetScoreText ()
{
ScoreText.text = "Score: " + Score.ToString ();
}
And this is my generateEnemy script:
public GameOverManager gameOverManager = null;
[HideInInspector]
public float minBlobSpawnTime = 2;
[HideInInspector]
public float maxBlobSpawnTime = 5;
[HideInInspector]
public bool generateBlobs = true;
[HideInInspector]
public GameObject blobPrefab = null;
[HideInInspector]
public GameObject blobRoot = null;
[HideInInspector]
public float minimumYPosition = -0.425f;
[HideInInspector]
public float maximumYPosition = 0.35f;
[HideInInspector]
public float minDaggerSpawnTime = 2;
[HideInInspector]
public float maxDaggerSpawnTime = 5;
[HideInInspector]
public bool generateDaggers = true;
[HideInInspector]
public GameObject daggerPrefab = null;
[HideInInspector]
public GameObject daggerRoot;
[HideInInspector]
public float minimumXPosition = -11.5f;
[HideInInspector]
public float maximumXPosition = 11.5f;
public Camera camera = null;
// Use this for initialization
void Start ()
{
generateBlobs = ((generateBlobs) && (blobPrefab != null) && (blobRoot != null));
generateDaggers = ((generateDaggers) && (daggerPrefab != null) && (daggerRoot != null));
if (camera == null)
{
Debug.LogError("GenerateEnemy: camera is not set in the inspector. Please set and try again.");
camera = Camera.main;
}
if (gameOverManager == null)
{
Debug.LogError("GenerateEnemy: gameOverManager not set in the inspector. Please set and try again.");
}
if (generateBlobs)
{
StartCoroutine(GenerateRandomEnemy(true, blobPrefab, blobRoot, minBlobSpawnTime, maxBlobSpawnTime));
}
if (generateDaggers)
{
StartCoroutine(GenerateRandomEnemy(false, daggerPrefab, daggerRoot, minDaggerSpawnTime, maxDaggerSpawnTime));
}
}
// Update is called once per frame
void Update ()
{
DestroyOffScreenEnemies();
}
// Spawn an enemy
IEnumerator GenerateRandomEnemy(bool generateOnYAxis, GameObject prefab, GameObject root, float minSpawnTime, float maxSpawnTime)
{
if ((prefab != null) && (gameOverManager != null))
{
if (!gameOverManager.GameIsPaused())
{
GameObject newEnemy = (GameObject) Instantiate(prefab);
newEnemy.transform.SetParent(root.transform, true);
// set this in the prefab instead
// newEnemy.transform.position = new Vector3(newEnemy.transform.parent.position.x, 0.5f, newEnemy.transform.parent.position.z);
// or if you want the y position to be random you need to do something like this
if (generateOnYAxis)
{
newEnemy.transform.position = new Vector3(newEnemy.transform.parent.position.x, Random.Range(minimumYPosition, maximumYPosition), newEnemy.transform.parent.position.z);
}
else
{
newEnemy.transform.position = new Vector3(Random.Range(minimumXPosition, maximumXPosition), newEnemy.transform.parent.position.y, newEnemy.transform.parent.position.z);
}
}
}
yield return new WaitForSeconds(Random.Range(minSpawnTime, maxSpawnTime));
StartCoroutine(GenerateRandomEnemy(generateOnYAxis, prefab, root, minSpawnTime, maxSpawnTime));
}
public void DestroyOffScreenEnemies()
{
GameObject[] enemies = GameObject.FindGameObjectsWithTag("enemy");
if ((enemies.Length > 0) && (camera != null))
{
for (int i = (enemies.Length - 1); i >= 0; i--)
{
// just a precaution
if ((enemies[i] != null) && ((camera.WorldToViewportPoint(enemies[i].transform.position).x > 1.03f) ||
(enemies[i].transform.position.y < -6f)))
{
Destroy(enemies[i]);
}
}
}
}
}
(This script has an generateEnemyCustomEditor script that references it, to show in the inspector)
Thank you :)
First of all, remove the static keyword from public static int movespeed = 20; and use GameObject.Find("ObjectMovementIsAttachedTo").GetComponent<Movement>(); to get the script instance if you want to modify movespeed variable from another script.
And faster when the player collects another 10 points and so on and so
on?
The solution is straight on. Use
if (Score % 10 == 0){
//Increement by number (4) movespeed from Movement script
movement.movespeed += 4;
}
to check if the Score is increased by 10 then increment movespeed by any value you want if that condition is true. It makes sense to put that in the OnTriggerEnter2D function after Score is incremented by 1.
Your new score script:
public class score : MonoBehaviour
{
public int Score;
public Text ScoreText;
private int moveSpeed;
void Start()
{
Score = 0;
SetScoreText();
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Pick Up"))
{
other.gameObject.SetActive(false);
Score = Score + 1;
if (Score % 10 == 0)
{
//Increement by number (4) movespeed from Movement script
moveSpeed += 4;
}
SetScoreText();
}
}
public int getMoveSpeed()
{
return moveSpeed;
}
void SetScoreText()
{
ScoreText.text = "Score: " + Score.ToString();
}
}
Since your Movement script will be instantiated, when you instantiate it, you send its reference to the Player script.
public class Movement : MonoBehaviour
{
public int movespeed = 20;
public Vector3 userDirection = Vector3.right;
score mySpeed;
void Start()
{
//Send Movement instance to the score script
GameObject scoreGameObject = GameObject.Find("GameObjectScoreIsAttachedTo");
mySpeed = scoreGameObject.GetComponent<score>();
}
public void Update()
{
transform.Translate(userDirection * mySpeed.getMoveSpeed() * Time.deltaTime);
}
}

Categories