I am integrating my game to VR and now i wanted to change my controlling. In the script given bellow when the player press the mouse button the gun fires the bullet but now in VR i don't want my game to be controlled by any controller. what i want is when player moves his head and the focus point comes to the Enemy it starts shooting without pressing any button(I mean auto shoot). what should i do??
grausing System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GunScript : MonoBehaviour {
public float damage = 10f;
public float range = 100f;
public float fireRate = 15f;
public float impactForce = 30f;
public Camera fpsCam;
public GameObject impactEffect;
private float nextTimeToFire = 0f;
// Update is called once per frame
void Update () {
if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
}
void Shoot()
{
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if (target != null)
{
target.TakeDamage(damage);
}
if(hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * impactForce);
}
GameObject ImpactEffectGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(ImpactEffectGO, 2f);
}
}
}
Since you already have an existing shooting mechanic, simply changing up the Update() should do what you want
void Update () {
if (Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
}
Related
GOAL
So I'm creating a top down arena battler type game, and I want you to be able to restart the game by pressing R.
PROBLEM
When I press R, the whole scene resets as it should, except all the enemies that were previously instantiated (and then destroyed) are spawned again, all at once.
CODE
This is the enemy spawning code :
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawn : MonoBehaviour
{
private float nextActionTime = 0.0f;
public float period = 5f;
public GameObject enemy;
void Update()
{
if (Time.time > nextActionTime ) {
nextActionTime += period;
GameObject clone = Instantiate(enemy, new Vector3(-1, 3, 0), Quaternion.identity);
clone.tag = "enemy";
}
}
}
This is the player code, responsible for restarting the scene (I have marked what I belive to be the relevantant sections with dashes) :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class PlayerController : MonoBehaviour
{
public Rigidbody2D rb;
public GameObject Shield;
public GameObject ShieldInstance;
public float moveSpeed = 4.3f;
public float sheildSpeed = 5f;
Vector2 movement;
AudioSource woop;
AudioSource waa;
----------------------------
GameObject[] enemies;
----------------------------
bool isDead = false;
void Start() {
woop = GameObject.Find("Main Camera/ShieldSFX").GetComponent<AudioSource>();
waa = GameObject.Find("Main Camera/DefeatSFX").GetComponent<AudioSource>();
}
void Update()
{
--------------------------------------------------------------
enemies = GameObject.FindGameObjectsWithTag("enemy");
--------------------------------------------------------------
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
Vector3 mouseScreen = Input.mousePosition;
Vector3 mouse = Camera.main.ScreenToWorldPoint(mouseScreen);
transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(mouse.y - transform.position.y, mouse.x - transform.position.x) * Mathf.Rad2Deg - 90);
if (Input.GetMouseButtonDown(0))
{
if (ShieldInstance != null || transform.GetChild(0).GetComponent<SpriteRenderer>().enabled == false) { return; }
woop.Play();
ShieldInstance = Instantiate(Shield, transform.position + transform.forward + transform.up, transform.rotation);
ShieldInstance.transform.parent = transform;
}
if (Input.GetMouseButtonUp(0))
{
if (ShieldInstance == null) { return; }
ShieldInstance.transform.parent = null;
ShieldInstance.GetComponent<ShieldController>().LaunchForward(sheildSpeed);
Destroy(ShieldInstance, 2.3f);
}
-------------------------------------------------------------------------------
if (Input.GetKey("r")) {
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
foreach (GameObject one in enemies) {
Destroy(one);
}
}
-------------------------------------------------------------------------------
}
void FixedUpdate() {
if (!isDead) {
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
}
void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "enemy") {
waa.Play();
GameObject.Find("Canvas/gameover").GetComponent<Text>().enabled = true;
transform.GetChild(0).GetComponent<SpriteRenderer>().enabled = false;
GetComponent<PolygonCollider2D>().enabled = false;
}
}
}
And this is the enemy code :
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyFollow : MonoBehaviour
{
public float moveSpeed;
public ParticleSystem explode;
AudioSource boom;
Vector2 movement;
GameObject player;
Rigidbody2D rb;
SpriteRenderer sr;
PolygonCollider2D pc;
void Start() {
rb = GetComponent<Rigidbody2D>();
sr = transform.GetChild(0).GetComponent<SpriteRenderer>();
pc = GetComponent<PolygonCollider2D>();
player = GameObject.Find("Player");
boom = GameObject.Find("Main Camera/ExplodeSFX").GetComponent<AudioSource>();
}
void Update()
{
Vector2 difference = (player.transform.position - new Vector3(2, .5f, 0)) - transform.position;
if (difference.x > 0) {
movement.x = 1;
} else if (difference.x < 0){
movement.x = -1;
} else {
movement.x = 0;
}
if (difference.y > 0) {
movement.y = 1;
} else if (difference.y < 0){
movement.y = -1;
} else {
movement.y = 0;
}
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "shield") {
StartCoroutine(ExplodeF());
}
}
private IEnumerator ExplodeF() {
explode.Play();
boom.Play();
sr.enabled = false;
pc.enabled = false;
yield return new WaitForSeconds(explode.main.startLifetime.constantMax);
Destroy(gameObject);
}
}
I would really appreciate any help!
If you want / need more details, just leave a comment :)
The problem is in Time.time, it is time since the start of the application, not since the start of the scene. So if you were in the game 30 secs, Time.time is 30 secs. If you reload the scene it is still 30 secs.
You have to count the time passed since entering the scene. Then it won't respawn all the enemies on scene reload.
When you restart the scene, everything is being destroyed and reset back except for the time.
The problem in your code is in the enemy spawner. Time.time returns the time passed since you started the game (and not since the scene was loaded). So, after the restart the if condition is true and the enemies are spawned.
If you want to count the time (in seconds) since the scene was loaded, what you can do is to add a variable in the enemy spawner class that would count the time
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawn : MonoBehaviour
{
private float nextActionTime = 0.0f;
private float timeSinceStart = 0;
public float period = 5f;
public GameObject enemy;
void Update()
{
if (timeSinceStart > nextActionTime ) {
nextActionTime += period;
GameObject clone = Instantiate(enemy, new Vector3(-1, 3, 0), Quaternion.identity);
clone.tag = "enemy";
}
timeSinceStart += Time.deltaTime;
}
}
See Time.deltaTime
so I have an issue about movement click on unity it's about when I click of course the player will be moving to the position I clicked but, I don't want if I clicked on the wall and another button the player will be on the last mouse I clicked, I already add some collider but the player just bypass the collider so collider doesn't have any effect
the explanation
and this the script
[Header("Tweak")]
[SerializeField] Transform target;
Vector2 targetPos;
public float speed = 5f;
// Start is called before the first frame update
void Start()
{
targetPos = transform.position;
}
// Update is called once per frame
void Update()
{
Move();
}
public void Move()
{
if (Input.GetMouseButtonDown(0))
{
targetPos = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition);
if ((targetPos.x >= transform.position.x))
{
transform.localScale = new Vector2(.5f, .5f);
}
else
{
transform.localScale = new Vector2(-.5f, .5f);
}
target.position = targetPos;
}
if ((Vector2)transform.position != targetPos)
{
transform.position = Vector2.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
}
}
You can do this using Raycast
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
if (hitInfo.collider.gameObject.tag == "Wall")
{
Debug.Log("tag");
//You can do what ever you want here.
}
}
}
I have a script which fires a linerenderer from a start to end position with each click. I want to have a linerender that is constant until the mouse button is released. Like a power charge. What do I need to add in the script to make this happen?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RayCastShot : MonoBehaviour
{
public float fireRate = 0.25f;
public float weaponRange = 50f;
public float hitForce = 100f;
public Transform gunEndLeft;
public Transform gunEndRight;
private Camera fpsCam;
private WaitForSeconds shotDuration = new WaitForSeconds(0.07f);
private LineRenderer lineRenderer;
private float nextFire;
public Material mat1;
public Material mat2;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
fpsCam = GetComponent<Camera>();
}
void Update()
{
if (Input.GetButtonDown("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
StartCoroutine(ShotEffect());
Vector3 rayOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));
RaycastHit hit;
lineRenderer.SetPosition(0, gunEndLeft.position);
lineRenderer.material = mat1;
if (Physics.Raycast(rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
{
lineRenderer.SetPosition(1, hit.point);
//get reference to hit point
}
if(hit.rigidbody !=null)
{
hit.rigidbody.AddForce(-hit.normal * hitForce);
}
else
{
lineRenderer.SetPosition(1, rayOrigin + (fpsCam.transform.forward * weaponRange));
}
}
if (Input.GetButtonDown("Fire2") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
StartCoroutine(ShotEffect());
Vector3 rayOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));
RaycastHit hit;
lineRenderer.SetPosition(0, gunEndRight.position);
lineRenderer.material = mat2;
//lineRenderer.material = new Material(Shader.Find("Particles/Priority Additive"));
if (Physics.Raycast(rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
{
lineRenderer.SetPosition(1, hit.point);
//get reference to hit point
}
if (hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * hitForce);
}
else
{
lineRenderer.SetPosition(1, rayOrigin + (fpsCam.transform.forward * weaponRange));
}
}
}
private IEnumerator ShotEffect()
{
lineRenderer.enabled = true;
yield return shotDuration;
lineRenderer.enabled = false;
}
}
Well you can start by use Input.GetButtonUp to stop the fire.
That way you can start on Input.GetButtonDown and stop only when buttonUp.
If you need to execute code every frame you can also use Input.GetButton.
That's the basic idea.
I am making a 2D point-and-click game where i want the player to move towards clicked objects. This is my code for moving the player towards a door:
using UnityEngine;
using System.Collections;
public class MoveOnClick : MonoBehaviour {
public GameObject door;
public GameObject player;
public float speed;
public Vector3 target;
void Update () {
if (Input.GetMouseButtonDown (0)) {
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector3.zero);
if (hit.collider != null) {
player.transform.position = Vector3.MoveTowards(player.transform.position, target, speed * Time.deltaTime);
}
}
}
}
The problem is that the player only moves one pixel per click. I want the player to move all the way to the door if the door is clicked.
That should work:
void Update () {
if (Input.GetMouseButtonDown (0)) {
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector3.zero);
target = hit.transform.position;
}
if (hit.collider != null) {
player.transform.position = Vector3.MoveTowards(player.transform.position, target, speed * Time.deltaTime);
}
}
Hello and thanks for reading this post.
I have 2 objects: A player Object and a JumpButton Object.
The Player object is the player. ofc. The JumpButton Object is an object that I want to make the player jump when you use a touch screen device aka android phone.
This is my Script that is assinged to my JumpButton: using UnityEngine; using System.Collections;
using UnityEngine;
using System.Collections;
public class JumpButtonScript : MonoBehaviour {
public GameObject player;
public GameObject JumpButton;
// Use this for initialization
void Start () {
player = GameObject.Find ("player");
}
// Update is called once per frame
void Update () {
if ((Input.touchCount == 1) && (Input.GetTouch(0).phase == TouchPhase.Began))
{
}
}
}
This is the script that allows me to control the player with arrow keys.
using UnityEngine;
using System.Collections;
public class RobotController : MonoBehaviour {
//This will be our maximum speed as we will always be multiplying by 1
public float maxSpeed = 2f;
public GameObject player;
public GameObject sprite;
//a boolean value to represent whether we are facing left or not
bool facingLeft = true;
//a value to represent our Animator
Animator anim;
//to check ground and to have a jumpforce we can change in the editor
bool grounded = true;
public Transform groundCheck;
public float groundRadius = 1f;
public LayerMask whatIsGround;
public float jumpForce = 300f;
private bool isOnGround = false;
void OnCollisionEnter2D(Collision2D collision) {
isOnGround = true;
}
void OnCollisionExit2D(Collision2D collision) {
anim.SetBool ("Ground", grounded);
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
isOnGround = false;
}
// Use this for initialization
void Start () {
player = GameObject.Find("player");
//set anim to our animator
anim = GetComponent <Animator>();
}
void FixedUpdate () {
//set our vSpeed
//set our grounded bool
grounded = Physics2D.OverlapCircle (groundCheck.position, groundRadius, whatIsGround);
//set ground in our Animator to match grounded
anim.SetBool ("Ground", grounded);
float move = Input.GetAxis ("Horizontal");//Gives us of one if we are moving via the arrow keys
//move our Players rigidbody
rigidbody2D.velocity = new Vector3 (move * maxSpeed, rigidbody2D.velocity.y);
//set our speed
anim.SetFloat ("Speed",Mathf.Abs (move));
//if we are moving left but not facing left flip, and vice versa
if (move > 0 && !facingLeft) {
Flip ();
} else if (move < 0 && facingLeft) {
Flip ();
}
}
void Update(){
if ((isOnGround == true && Input.GetKeyDown (KeyCode.UpArrow)) || (isOnGround == true && Input.GetKeyDown (KeyCode.Space))) {
anim.SetBool("Ground",false);
rigidbody2D.AddForce (new Vector2 (0, jumpForce));
}
if (isOnGround == true && Input.GetKeyDown (KeyCode.DownArrow))
{
gameObject.transform.localScale = new Vector3(transform.localScale.x, 0.2f, 0.2f);
}
if (isOnGround == true && Input.GetKeyUp (KeyCode.DownArrow))
{
gameObject.transform.localScale = new Vector3(transform.localScale.x, 0.3f, 0.3f);
}
}
//flip if needed
void Flip(){
facingLeft = !facingLeft;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
As you can see, then I managed to make the player move on arrow keys, but how can I make it jump when I hit the jump button (touch Screen press), as on an Android Phone?
I really hope you can help me.
If your problem is how to handle input, try this code we will make ray from camera to mousepos in screen and check tag to see what we hitted
public class handleInput: MonoBehaviour {
void Update () {
if (Input.GetMouseButtonDown (0)) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
if (hit.collider.tag=="jumpbutton"){
jump();
}
}
}
}
}
and for the jumping part you can do this , adding a force to player to send him up and gravity should pull him down
if (grounded == true)
{
rigidbody.AddForce(Vector3.up* jumpSpeed);
grounded = false;
}