My script doesn't activate UI and doesn't play animations - c#

Hey guys I have a made two scripts to handle door opening.
Script 1 - Raycast
Script 2 - The door opening script
I have the raycast on the player camera and I have script 2 on the door.
But there is a problem.
In script 2, I have code that makes UI active and inactive and code that does the door animation
SCRIPT 1 -
using System.Collections.Generic;
using UnityEngine;
public class PlayerCasting : MonoBehaviour
{
public Camera FPScam;
public float range = 6;
public static float ToTarget;
void Update()
{
RaycastHit Hit;
if (Physics.Raycast(FPScam.transform.position, FPScam.transform.forward, out Hit, range))
{
ToTarget = Hit.distance;
}
}
}
SCRIPT 2 -
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DoorOpen : MonoBehaviour
{
public float Distance;
public GameObject key;
public GameObject reason;
public GameObject Hinge;
public AudioSource DoorCreak;
// Update is called once per frame
void Update()
{
Distance = PlayerCasting.ToTarget;
}
private void OnMouseOver()
{
if (Distance <= 3.5f)
{
key.SetActive(true);
reason.SetActive(true);
}
if (Input.GetButtonDown("Action"))
{
if (Distance <= 3.5f)
{
key.SetActive(false);
reason.SetActive(false);
this.GetComponent<BoxCollider>().enabled = false;
Hinge.GetComponent<Animation>().Play("DoorOpenAnim");
DoorCreak.Play();
}
}
}
private void OnMouseExit()
{
key.SetActive(false);
reason.SetActive(false);
}
}
But, the UI doesn't activate nor does the animation plays when I click 'E' and when the Raycast distance <= 3.5.

I have the raycast on the player camera
Since you're using OnMouseOver() and OnMouseExit() your methods will only work when the player's mouse is on the thing you want to raycast.
Make sure that the raycast is actually pointing the same direction the mouse cursor is. You use use Debug.Raycast() to visually see where the raycast is going.
If the raycast is going in the direction you want it to and it's still not working try a different way of communicating through the scripts and avoid using OnMouseOver().
For example you could try something like this:
public class PlayerCasting : MonoBehaviour
{
public Camera FPScam;
public float range = 6;
public static float ToTarget = 0f;
public static GameObject HoveredObject = null; // <----
void Update()
{
RaycastHit Hit;
if (Physics.Raycast(FPScam.transform.position, FPScam.transform.forward, out Hit, range))
{
ToTarget = Hit.distance;
HoveredObject = Hit.collider.gameObject; // <----
}
}
}
public class DoorOpen : MonoBehaviour
{
public float Distance;
public GameObject key;
public GameObject reason;
public GameObject Hinge;
public AudioSource DoorCreak;
// Update is called once per frame
void Update()
{
if (PlayerCasting.HoveredObject == gameObject)
{
Distance = PlayerCasting.ToTarget;
CheckDistance();
}
}
private void CheckDistance()
{
if (Distance <= 3.5f)
{
key.SetActive(true);
reason.SetActive(true);
if (Input.GetButtonDown("Action"))
{
key.SetActive(false);
reason.SetActive(false);
this.GetComponent<BoxCollider>().enabled = false;
Hinge.GetComponent<Animation>().Play("DoorOpenAnim");
DoorCreak.Play();
}
}
else
{
key.SetActive(false);
reason.SetActive(false);
}
}
private void OnMouseExit()
{
key.SetActive(false);
reason.SetActive(false);
}
}

Related

Not able to destroy the prefeb object in unity

using UnityEngine;
public class Gun : MonoBehaviour
{
public GameObject enemy; // Not necessary, only if you need a reference to the enemy for future actions
public float damage = 100f;
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Shoot();
}
}
void Shoot() // The are a general routine to program on all laguajes, you should name all functions with Uppercase start letter
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit))
{
// Target targ = GetComponent<Target>(); //
Target targ = hit.collider.GetComponent<Target>();
// Now, you have the enemy script values referenced and you can make your actions.
// I dont understand next code, your are not referenig enemy never, I mean, enemy ever is null
if (enemy != null)
{
Destroy(enemy);
}
}
target.cs:
using UnityEngine;
public class Target : MonoBehaviour
{
// Start is called before the first frame update
public float health = 50f;
public void TakeDamage (float amount)
{
health -= amount;
if (health <= 0f)
{
Die();
}
}
void Die()
{
Destroy(gameObject);
}
}

Unity - help needed to touch and hold UI button to call update method and auto fire (here is the script)

I am a newbie with no coding experience just started using unity I was following brackeys Ray cast shooting video,https://youtu.be/THnivyG0Mvo,, and I created the gun script but I wanted to turn it into mobile so I wanted to autofire by holding a UI button.
plz, I need help me know no code.
this is my code.
I was thinking is there a way to put something in place of input.getbutton to make a button that will autofire on holding.
Thanks & sorry if this is a silly question
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.VisualScripting;
public class Gun : MonoBehaviour
{
public float damage = 10f;
public float range = 100f;
public float fireRate = 15f;
public float impactForce = 30f;
public Camera fpsCam;
public ParticleSystem muzzleFlash;
public GameObject impactEffect;
private float nextTimeToFire = 0f;
// Update is called once per frame
public void Update()
{
if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
}
public void Shoot()
{
muzzleFlash.Play();
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit,
range))
{
Enemy enemy = hit.transform.GetComponent<Enemy>();
if (enemy != null)
{
enemy.TakeDamage(damage);
}
if (hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * impactForce);
}
GameObject impactGO = Instantiate(impactEffect, hit.point,
Quaternion.LookRotation(hit.normal));
Destroy(impactGO, 2f);
}
}
}
Create a Button, and add a new script to it. This script will be responsible for handling the button state. Essentially what we need to do is..
When OnPointerDown happens, set a value to indicate the button is held down. When OnPointerUp happens, reset the value.
using UnityEngine;
using UnityEngine.EventSystems;
public class ClickAndHoldButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler
{
public bool IsHeldDown => isHeldDown;
private bool isHeldDown;
public void OnPointerDown(PointerEventData eventData)
{
isHeldDown = true;
}
public void OnPointerUp(PointerEventData eventData)
{
isHeldDown = false;
}
public void OnPointerEnter(PointerEventData eventData)
{
}
}
Then in Update of your gun, you will check the button state to see if it is being held down.
public ClickAndHoldButton mobileFireButton;
void Update()
{
if (Time.time >= nextTimeToFire && (
Input.GetButton("Fire1") ||
mobileFireButton.IsHeldDown))
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
}

Is there a way to have Delay timer or cutscene? Unity March 28/21 update

What I'm trying to do is have my player stop moving so I can play animation through a trigger-event or just a custscene.
What I expect was for one of them to trigger the timer then play animation>player move.. like a cut-scene
Also there are no errors In any of them They just didn't stop player from moving or just stop the player when starting the game(or when I press play it just set forwardMovement to 0)
Here's the code I use:
public class Player_controls : MonoBehaviour
{
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class Player_controls : MonoBehaviour
{
public int forwardMovement = 1000;
public void Update()
{
rb.AddForce(0, 0, forwardMovement * Speed * Time.deltaTime);
}
}
}
Things that I tried:
public void ForwardMovement()
{
forwardMovement = 0;
Invoke("Action", 2f);
}
public void Action ()
{
forwardMovement = 1000 ;
}
Which only works for ForwardMovement(); method nothing else
I tried these two things also:
Public static class MonoExtensions
{
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public float Delayer = 10f;
public static class MonoExtensions
{
public static void Timed_delay(this MonoBehaviour mono,Action function, float Delayer)
{
mono.StartCoroutine(Timed_delayRoutine(function,Delayer));
}
static IEnumerator Timed_delayRoutine(Action function, float Delayer)
{
yield return new WaitForSeconds(Delayer);
function();
}
public class `Player_Controls`: MonoBehaviour
{
public void PM ()
{
forwardMovement = 0;
}
void OnTriggerEnter(Collider other)
{
if (CompareTag("Power_up"))
{
this.Timed_delay(PM, Delayer);
}
}
}
Which just stop the player from moving an nothing else.
What I also tried was:
public class Player_Controls : MonoBehaviour
{
void Start()
{
StartCoroutine(ForwardMovement());
}
IEnumerator ForwardMovement()
{
forwardMovement = 0;
yield return new waitforseconds(Delayer);
forwardMovement = 1050;
}
void OnTriggerEnter(collider other)
{
if (CompareTag("Power_up"))
{
ForwardMovement();
}
}
}
Which did not work as in(it works but the timer part does nothing, so the player can't move when started the game )
Different way I tried
public class Player_Controls : MonoBehaviour
{
OnTriggerEnter(collider other)
{
Startcroutine(ForwardMovement ));
}
}
it didn't work but no Errors.
I tried this one by jazzhar:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class Player_controls : MonoBehaviour
{
// Drag the player in the inspector here;
public Rigidbody rb;
// Youre speed variable for movement.
public float Speed = 5;
// Youre speed variable for movement.
public int forwardMovement = 1000;
// Set this "stopmoving" bool to true to prevent movement.
public bool stopMoving = false;
// Create and select the right layer in the inspector.
public LayerMask WichObjectStopsMovement;
public void Update()
{
// if stopMoving = true than Dont Add force.
if (stopMoving == false)
{
rb.AddForce(0, 0, forwardMovement * Speed * Time.deltaTime);
}
}
private void OnCollisionEnter(Collision collision)
{
// if you're player touches a object and that object's layer
// is the same as "WichObjectStopsMovement" than disable Movement.
if (collision.collider.gameObject.layer == WichObjectStopsMovement)
{
stopMoving = false;
}
}
}
It sorta works in a way if you set if
if (stopMoving == true)
{
rb.AddForce(0, 0, forwardMovement * Speed * Time.deltaTime);
}
and
if (collision.collider.gameObject.layer == WichObjectStopsMovement)
{
stopMoving = true;
}
then the player would be able to move but it will not trigger if hit the cube
it didn't work either but no Errors.
And some other timers I did but forgotten....
_________________________________________________________________March/6/21
public float Delayer = 10.0f;
I think found solution by doing this
private void OnTriggerEnter(Collider other)
{
if (CompareTag("Power_up"))
{
Delayer -= Time.deltaTime; <- this part giving me the error
if (Delayer => 0)
{
forwardMovement = 0;
}
}
}
but their one problem it giving me the this error Cannot convert lambda expression to type 'bool' because it is not a delegate type [Assembly-CSharp]csharp(CS1660) I don't know much about this even searching about doesn't help either
__________________________________________________________________March 28/21
this script is under player controls
this one works I made sure by doing Debug.Log("test");
void OnTriggerExit(Collider collision)
{
if (collision.gameObject.CompareTag("Power_up"))
{
forwardMovement = 0;
}
if (forwardMovement <= 0)
{
Debug.Log("test");
}
This might be a solution to you're problem, Fire-Source!:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class Player_controls : MonoBehaviour
{
// Drag the player in the inspector here;
public Rigidbody rb;
// Youre speed variable for movement.
public float Speed = 5;
// Youre speed variable for movement.
public int forwardMovement = 1000;
// Set this "stopmoving" bool to true to prevent movement.
public bool stopMoving = false;
// Create and select the right layer in the inspector.
public LayerMask WichObjectStopsMovement;
public void Update()
{
// if stopMoving = true than Dont Add force.
if (stopMoving == false)
{
rb.AddForce(0, 0, forwardMovement * Speed * Time.deltaTime);
}
}
private void OnCollisionEnter(Collision collision)
{
// if youre player touches a object and that object's layer
// is the same as "WichObjectStopsMovement" than disable Movement.
if (collision.collider.gameObject.layer == WichObjectStopsMovement)
{
stopMoving = false;
}
}
}
This code uses a LayerMask, to create 1 click on any object and in the inspector go:
Click on Layer:
Add Layer:
Write in User Layer 6, StopMovement (or anything else).
Than in the object that should stop player movement:
Click on layer:
Than select the Layer that says StopMovement.
And in you're player's script drag the object into the rb variable.
and in "WichObjectStopsMovement" assign the StopMovement layer.
This should take care of everything is that ok?

Unity raycast possible bug?

this is my code for raycast in my school project game. If I put script on object everything is working just fine. But if I close Unity and reopen my project, the value of "jakDaleko" = distance stays locked on 1129.395 instead of changing every frame.
What should I change so it will work everytime and not just the first time ipress play button.
Here's my code.
script 1 = raycast
public class SmerDivani : MonoBehaviour {
public static float VzdalenostOdCile;
public float VzdalenostOdCileInterni;
// Update is called once per frame
void Update() {
RaycastHit Hit;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out Hit)) {
VzdalenostOdCileInterni = Hit.distance;
VzdalenostOdCile = VzdalenostOdCileInterni;
}
}
}
Second script
public class TabuleMesto1 : MonoBehaviour
{
public float JakDaleko;
public GameObject AkceTlacitko;
public GameObject AkceText;
public GameObject UIQuest;
public GameObject ThePlayer;
public GameObject NoticeCam;
void Update() {
JakDaleko = SmerDivani.VzdalenostOdCile;
}
void OnMouseOver() {
if (JakDaleko <= 5) {
AkceTlacitko.SetActive(true);
AkceText.SetActive(true);
}
if (JakDaleko > 5)
{
AkceTlacitko.SetActive(false);
AkceText.SetActive(false);
}
if (Input.GetButtonDown("Akce")) {
if (JakDaleko <= 5) {
AkceTlacitko.SetActive(false);
AkceText.SetActive(false);
UIQuest.SetActive(true);
NoticeCam.SetActive(true);
ThePlayer.SetActive(false);
}
}
}
void OnMouseExit() {
AkceTlacitko.SetActive(false);
AkceText.SetActive(false);
}
}
I'm not quite sure what you're trying to achieve? Maybe this should "fix" your problem, you're not clearing the distance if the raycast don't hits....
void Update() {
RaycastHit Hit;
if (Physics.Raycast(transform.position, transform.forward, out Hit)) {
VzdalenostOdCileInterni = Hit.distance;
}
else {
VzdalenostOdCileInterni = 0.0f;
}
VzdalenostOdCile = VzdalenostOdCileInterni;
}
Additionally I think you should use transform.forward instead of transform.TransformDirection(Vector3.forward)
I think that the biggest problem was the name of the file. For some reason, my stupidity included, the solution was to rename the script from table1 to table_1

Bullet not going towards target

Not sure why, I've done this sort of this a bunch of times, but this is giving me some issues. Making a project for Game AI, I have a whole bunch of stuff already done, now just making some turrets that if the player is in a certain range it will fire, which I have already. The turret fires the bullet and then for some reason they just start destroying themselves and they don't go towards my player. Wondering if anyone on here can help, thanks in advance!
Some details you may need to know:
I have a Base, a Gun nose and a Gun for my turret. My Gun has a GunLook.cs script that makes it look at the player (so when they shoot it should go towards them), I'm not sure if that has anything to do with why I'm having these issues, but I'll post that code as well just incase
How my Hierchy for my turret is
Turret_AI (Base)
Gun (child of Turret_AI)
bulletSpawn (child of Gun)
Gun_Nose (child of turret_AI)
bulletSpawn is an empty GameObject I created in hopes to solve my problem. I set it just off the Gun so that it wouldn't just collide with gun and destroy itself (what I thought it might be doing, but not correct).
That should be all the info needed, if anyone needs more I will be checking this every 2 seconds so let me know and I will get back to you with quick response.
TurretScript.cs
(I did set the GameObject to Player in Unity, before anyone asks)
using UnityEngine;
using System.Collections;
public class TurretScript : MonoBehaviour {
[SerializeField]
public GameObject Bullet;
public float distance = 3.0f;
public float secondsBetweenShots = 0.75f;
public GameObject followThis;
private Transform target;
private float timeStamp = 0.0f;
void Start () {
target = followThis.transform;
}
void Fire() {
Instantiate(Bullet, transform.position , transform.rotation);
Debug.Log ("FIRE");
}
void Update () {
if (Time.time >= timeStamp && (target.position - target.position).magnitude < distance) {
Fire();
timeStamp = Time.time + secondsBetweenShots;
}
}
}
GunLook.cs
// C#
using System;
using UnityEngine;
public class GunLook : MonoBehaviour
{
public Transform target;
void Update()
{
if(target != null)
{
transform.LookAt(target);
}
}
}
BulletBehavior.cs
using UnityEngine;
using System.Collections;
public class BulletBehavior : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (rigidbody.velocity.magnitude <= 0.5)
Destroy (gameObject);
}
void OnCollisionEnter(Collision collision)
{
if (collision.collider)
{
if(collision.gameObject.tag == "Enemy" || collision.gameObject.tag == "EnemyProjectile")
{
Physics.IgnoreCollision(rigidbody.collider,collision.collider);
//Debug.Log ("Enemy");
}
if(collision.gameObject.tag == "SolidObject")
{
Destroy(gameObject);
}
if(collision.gameObject.tag == "Player")
{
Destroy(gameObject);
}
}
}
}
You're never moving your bullet.
public class BulletBehavior : MonoBehaviour
{
private const float DefaultSpeed = 1.0f;
private float startTime;
public Vector3 destination;
public Vector3 origin;
public float? speed;
public void Start()
{
speed = speed ?? DefaultSpeed;
startTime = Time.time;
}
public void Update()
{
float fracJourney = (Time.time - startTime) * speed.GetValueOrDefault();
this.transform.position = Vector3.Lerp (origin, destination, fracJourney);
}
}
Then call it like so:
void Fire()
{
GameObject bullet = (GameObject)Instantiate(Bullet, transform.position , transform.rotation);
BulletBehavior behavior = bullet.GetComponent<BulletBehavior>();
behavior.origin = this.transform.position;
behavior.destination = target.transform.position;
Debug.Log ("FIRE");
}
Note: If you're trying to mix this approach with trying to use physics to move the bullet you may end up with strange results.

Categories

Resources