Unity problem activating a function with parameters in camera from another script in GameObject Enemy - c#

I have a script that makes the camera do a shake by putting a button because
It is a public access function, if I do it that way when placing a button it works well but what I cannot achieve is to call the function so that every time my player collides with an enemy he makes the shake. I hope you can help me.
The shake code in camera is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScreenShaker : MonoBehaviour {
private float shakeAmount = 0.5f;
private float shakeTime = 0.0f;
private Vector3 initialPosition;
private bool isScreenShaking = false;
void Update () {
if(shakeTime > 0)
{
this.transform.position = Random.insideUnitSphere * shakeAmount + initialPosition;
shakeTime -= Time.deltaTime;
}
else if(isScreenShaking)
{
isScreenShaking = false;
shakeTime = 0.0f;
this.transform.position = initialPosition;
}
}
public void ScreenShakeForTime(float time)
{
initialPosition = this.transform.position;
shakeTime = time;
isScreenShaking = true;
}
}
The enemy code is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ControladorEnemigoCirculoMediano : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
Here I don't know what to call the public void function ScreenShakeForTime (float time);
I already tried many things online but when my character comes into contact with the character, I don't do the shake in the camera.
}
}
}

You can create Unity-singleton in your ScreenShaker class like:
class ScreenShaker
{
public static ScreenShaker Instance {private set; get;};
void Awake() {
Instance = this;
}
}
And than from any place to call like:
ScreenShaker.Instance.ScreenShakeForTime(2f);
This is the easiest way, but maybe it's better to create standard singeleton(it's up to you).
And also don;t forget to destroy it on OnDestroy()

can you tell me in enemy game object collider isTrigger is enable or not
if it is not enable then use OnColliderEnter2D(Collision2D other){} for collision detection

Related

I am making a turret but it won't shoot

I am making a turret that shoots a bullet at a set rate, but when the timer is done it doesn't spawn a new bullet even though it doesn't say i have any errors. the bullet has a simple script where it moves at a set speed either left or right, and gets destroyed on impact with an object. the turret does not have a collider right now so I know that's not the problem.
Here is the code for shooting:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TurretShoot : MonoBehaviour
{
public GameObject bullet;
public int bullet_rate = 10;
public int timer;
public Transform SpawnPoint;
void Start()
{
timer = bullet_rate * 10;
}
// Update is called once per frame
void Update()
{
if (timer == 0)
{
Instantiate(bullet, SpawnPoint.transform);
timer = bullet_rate * 10;
}
else
{
timer -= 1;
}
}
}
Here is the bullet code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletMove : MonoBehaviour
{
public int moveDirection;
public int moveSpeed;
void Start()
{
}
// Update is called once per frame
void Update()
{
this.transform.position += new Vector3(moveDirection * moveSpeed, 0, 0);
}
void onCollisionEnter2D(Collider2D col)
{
if (col.GetComponent<Collider>().name != "turret_top")
{
Destroy(this);
}
}
}
Here is the inspector for the turret:
Probably what is happening is it get's destroyed when it spawns.
I don't have a collider on the turret
You aren't instantiating it at the turrent. You are simply setting the parent when you are instantiating it:
public static Object Instantiate(Object original, Transform parent);
Meaning it is probally spawning at Vector3.Zero and instantly gets de-spawn.
Rather use the overload method of:
public static Object Instantiate(Object original, Vector3 position, Quaternion rotation);
That way you are spawning it the location you want. This is how you would go about it:
var bulletObj = Instantiate(bullet, SpawnPoint.transform.position, Quaternion.Identity);
bulletObj.transform.parent = SpawnPoint.transform;
timer = bullet_rate * 10;

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 Sword Collision Attack

Hey guys I want to make a sword attack. But I get the error of:
NullReferenceException: Object reference not set to an instance of an
object
These are my codes:
My weaponattack script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weaponattack : MonoBehaviour
{
Enemy Enemy;
public float power;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void OnTriggerEnter(Collider col)
{
if(col.tag == "Enemy")
{
var kılıc = GetComponent<Enemy>();
Enemy.currentHealt -= 10;
Enemy.TakeDamage();
Debug.Log("Düşman Vuruldu");
}
}
}
This is my Enemy Health scrpt:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour {
public float currentHealt;
public float maxHealth;
// Use this for initialization
void Start () {
currentHealt = maxHealth;
}
// Update is called once per frame
void Update () {
}
public void TakeDamage()
{
currentHealt -= 10;
if(currentHealt < 0)
{
die();
}
}
void die()
{
Destroy(gameObject);
}
}
Can you helo em I couldnt understan why these codes are not working why am I getting that error.
I think your problem is in this line here GetComponent<Enemy>(); This needs a game object to get the component of
Enemy = col.GetComponent<Enemy>();
Should be what you're doing
You also may have issue calling your variable Enemy exactly the same as your class Enemy, I would change this to Enemy enemy; and
enemy = col.GetComponent<Enemy>();
respectivley
It seems pretty straightforward. You don't assign an Enemy to Weaponattack and so it's barfing when you first reference Enemy (Enemy.currentHealt). Either make Enemy public or a SerializedField so you can assign it in the Inspector, or however else you want to get an Enemy into Weaponattack.
Also don't name your property the same name as your script (Enemy Enemy). Surprised you didn't get a compile error.
EDIT Based on comments:
Enemy enemy;
public void OnTriggerEnter(Collider col)
{
if(col.tag == "Enemy")
{
var kılıc = GetComponent<Enemy>();
kilic.currentHealt -= 10;
kilic.TakeDamage();
Debug.Log("Düşman Vuruldu");
}
}
This also assumes you have an Enemy attached to your Weaponattack (GetComponent)

CollisionOnEnter how to detect if an object is colliding?

im pretty new to C# and Unity and i try to make an Angry Birds clone, and im stuck on this problem.
I want to change the mass of the mass of the Gameobject(in my case the woodblock) when the bird is flying and hits the object, it should change from Mass: 1 to Mass: 0.2
here is a screenshot of the scene
I created two Methods and it works in a weird way but every time i start the game the Mass gets not to 1 rather in 0.2. It should only change when the bird collides with the woodblock.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Wall : MonoBehaviour
private float wallMass;
private bool isHit;
private Rigidbody2D rb;
void Start()
{
rb = gameObject.GetComponent<Rigidbody2D>();
wallMass = 1.0f;
isHit = false;
}
void Update()
{
CollisionOn(isHit);
}
private void CollisionOn(bool isTrue)
{
rb.GetComponent<Rigidbody2D>().mass = wallMass;
if (isTrue)
{
DecreaseMass();
}
}
void DecreaseMass()
{
rb.GetComponent<Rigidbody2D>().mass = 0.2f;
}
Use these 2 events on a MonoBehaviour, that's attached to the box.
Called when collision occurs
void OnCollisionEnter2D(Collision2D col)
{
GetComponent<Rigidbody2D>().mass = wallMass;
}
Same way when Collision ends.
void OnCollisionExit2D(Collision2D other)
{
GetComponent<Rigidbody2D>().mass = 0.2f;
}

unity5 enemyDamage prob

im having a problem from my enemyDamage script in unity5 when i play it and stick to the enemy i died instantly even the enemy damage is 10 and my health was 100
well this is my first time to make this things on unity hope you helps me :(
heres my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemydmg : MonoBehaviour {
public float damage;
public float damagerate;
public float pushbackforce;
float nextdamage;
bool playerInRange = false;
GameObject theplayer;
playerHealth theplayerhealth;
// Use this for initialization
void Start () {
nextdamage = Time.time;
theplayer = GameObject.FindGameObjectWithTag ("Player");
theplayerhealth = theplayer.GetComponent<playerHealth> ();
}
// Update is called once per frame
void Update () {
if (playerInRange)
Attack ();
}
void OnTriggerEnter (Collider other)
{
if (other.tag == "Player")
{
playerInRange = true;
}
}
void OnTriggerExit (Collider other)
{
if (other.tag == "Player")
{
playerInRange = false;
}
}
void Attack()
{
if (nextdamage <= Time.time)
{
theplayerhealth.addDamage(damage);
nextdamage = Time.time + damagerate;
pushback (theplayer.transform);
}
}
void pushback(Transform pushObject)
{
Vector3 pushDirection = new Vector3 (0, (pushObject.position.y - transform.position.y), 0).normalized;
pushDirection *= pushbackforce;
Rigidbody pushedRB = pushObject.GetComponent<Rigidbody> ();
pushedRB.velocity = Vector3.zero;
pushedRB.AddForce (pushDirection, ForceMode.Impulse);
}
}
and this was my playerhealth
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerHealth : MonoBehaviour {
public float fullhealth;
float currentHealth;
// Use this for initialization
void Start () {
currentHealth = fullhealth;
}
// Update is called once per frame
void Update () {
}
public void addDamage(float damage)
{
currentHealth -= damage;
if (currentHealth <= 0) {
makeDead ();
}
}
public void makeDead()
{
Destroy (gameObject);
}
}
theplayerhealth = theplayer.GetComponent<playerHealth> ();
I think this line of code fails you because the player is a GameObject. theplayerhealth is or should already be initialized in your other script. I think you could approach polymorphism in a better way.
public class enemydmg : playerHealth{
}
This will allow you to directly inherit everything you need from the playerHealth script without having to grab extra components. You can also use this technique for may other scripts in the future.
Another approach that you could use is calling your class directly:
playerHealth.addDamage(damage);
From now on when you name your scripts use capitalization. PlayerHealth, EnemyDamage, etc... That's just a pro-tip to make your code look a bit cleaner when you're doing things like this. (Optional)

Categories

Resources