I am creating a FPS game, my player has abilities and her ultimate is Jett's ultimate from Valorant (Her weapon switches to 5 knives that she can throw at enemies) I've managed to make the weapon switch to the knives but when I press the Mouse Left-Click nothing happens. I disabled the script that controls the gun so that the player does shoot bullets, have muzzle flash etc but whether its enabled or disabled the knives don't work. I added debug logs and they arent being called, I use the same button to shoot the gun as throwing the knife. I have also tested it without the 'readyToThrow' variable and 'totalThrows' variable.
Update Method:
void Update()
{
if (Time.time >= QabilityTimer && Input.GetKeyDown(KeyCode.Q))
{
Dash();
QabilityTimer = Time.time + Qcooldown;
}
if (Time.time >= EabilityTimer && Input.GetKeyDown(KeyCode.E))
{
SpeedBoost();
EabilityTimer = Time.time + Ecooldown;
}
if (meterButton.currentProgress == meterButton.maxProgress)
{
ultReady = true;
// Debug.Log("ult ready");
if (Input.GetKeyDown(KeyCode.X))
{
//disable the gun script whilst ult is active.
GameObject gun = GameObject.Find("Guns");
gun.GetComponent<Guns>().enabled = false;
weaponSelection.EunhaUltKnife();
EunhaUltimate();
}
}
if (ultActive)
{
ultTimer -= Time.deltaTime;
}
if (ultTimer <= 0)
{
ResetUltimate();
}
}
Ultimate Method:
public void EunhaUltimate()
{
ultActive = true;
if (Input.GetKeyDown(KeyCode.Mouse0) && readyToThrow && totalThrows > 0)
{
Debug.Log("working");
readyToThrow = false;
GameObject projectile = Instantiate(objectToThrow, attackPoint.position, cam.rotation);
Rigidbody projectileRB = projectile.GetComponent<Rigidbody>();
Vector3 forceToAdd = cam.transform.forward * throwForce + transform.up * throwUpwardForce;
projectileRB.AddForce(forceToAdd, ForceMode.Impulse);
totalThrows--;
Invoke(nameof(ReserThrow), throwCooldown);
}
}
Looks like you can only get into the EunhaUltimate() if you're holding down X:
if (meterButton.currentProgress == meterButton.maxProgress)
{
ultReady = true;
// Debug.Log("ult ready");
if (Input.GetKeyDown(KeyCode.X))
{
//disable the gun script whilst ult is active.
GameObject gun = GameObject.Find("Guns");
gun.GetComponent<Guns>().enabled = false;
weaponSelection.EunhaUltKnife();
EunhaUltimate();
}
}
Try moving the call to EunhaUltimate() outside of that IF statement. You'll need to have a trigger to show when you've pushed X to trigger the ultimate, but it looks like you're currently doing that inside EunhaUltimate(), with the ultActive = true; line.
Other than setting ultActive = true;, all your EunhaUltimate() seems to do is to check the keyboard press, so I'd recommend rewriting your first snippet as follows:
void Update()
{
if (Time.time >= QabilityTimer && Input.GetKeyDown(KeyCode.Q))
{
Dash();
QabilityTimer = Time.time + Qcooldown;
}
if (Time.time >= EabilityTimer && Input.GetKeyDown(KeyCode.E))
{
SpeedBoost();
EabilityTimer = Time.time + Ecooldown;
}
if (meterButton.currentProgress == meterButton.maxProgress)
{
ultReady = true;
// Debug.Log("ult ready");
if (Input.GetKeyDown(KeyCode.X))
{
//disable the gun script whilst ult is active.
GameObject gun = GameObject.Find("Guns");
gun.GetComponent<Guns>().enabled = false;
weaponSelection.EunhaUltKnife();
ultActive = true; // <--- This is a change
}
}
if (ultActive)
{
EunhaUltimate(); // <-- this is a change
ultTimer -= Time.deltaTime;
}
if (ultTimer <= 0)
{
ResetUltimate();
}
}
Try using Input.GetKey(KeyCode.Mouse0) or Input.GetKeyUp(KeyCode.Mouse0) instead Input.GetKeyDown(KeyCode.Mouse0).
Related
I have a problem in which my ammo won't decrease when I shoot until I wait for a certain Amount of time. I'm currently using Photon as my Network System for my game and my gun code from Brackeys (https://www.youtube.com/watch?v=kAx5g9V5bcM&lc=UghlAulu5dH90HgCoAEC). This is maybe related to internet problems and delays but I'll show you the code I use:
void Update()
{
if(!photonView.IsMine) return;
if (!canShowAmmo)
{
ammoText.text = "Ammo: " + currentAmmo;
}
if (isStarted && (owner.openPanel || MultiplayerManager.main.roomManager.gameDone))
{
if (isScoped)
{
Scope();
}
return;
}
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if(autoOrSemi == true){
if(Input.GetButton("Fire1") && Time.time >= nextTime){
nextTime = Time.time + 1f/fireRate;
Shoot();
}
}
if(autoOrSemi == false){
if(Input.GetButtonDown("Fire1") && Time.time >= nextTime){
nextTime = Time.time + 1f/fireRate;
Shoot();
}
}
if (Input.GetButtonDown("Fire2"))
{
Scope();
}
}
public void Shoot(){
MuzzleFlash.Play();
currentAmmo--;
AudioSource.PlayClipAtPoint(shotSound, transform.position);
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range)){
Debug.Log(hit.transform.name);
IDamageable target = hit.collider.gameObject.GetComponent<IDamageable>();
if (target != null)
{
if (hit.collider != owner.GetComponent<Collider>())
{
target.TakeDamage(damage);
owner.score += (int) damage;
owner.ScoreUpdate();
}
}
if(hit.rigidbody != null){
hit.rigidbody.AddForce(-hit.normal * impactForce);
}
GameObject effect = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(effect, 2f);
}
}
public IEnumerator Reload(){
isReloading = true;
Debug.Log("Reloading");
canShowAmmo = true;
ammoText.text = "Reloading...";
yield return new WaitForSeconds(reloadTime - .25f);
yield return new WaitForSeconds(.25f);
canShowAmmo = false;
currentAmmo = maxAmmo;
isReloading = false;
}
so if I was correct and it's caused by lag or I was wrong and didn't have any relation to the Network, please I need a solution. Thanks.
Sorry my bad, I may just found a solution: just add a new private bool and set it to true inside the if function derHugo presented below or above this comment and if bool is false then shooting is disabled then after reloading inside the enumerator after isReloading = false, make the bool to false
I think you issue are concurrent Coroutines!
you are doing
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
This will start a new routine every frame while the condition is met.
You rather want to do e.g.
if (!isReloading && currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if(isReloading) return;
I been trying to create an AI for the enemy to patrol between some points and, when spot player in a certain range, the enemy stop the patrol and follows the player.
The thing is, if I only have the enemy to follow the player, works perfectly the same happens with just the patrol, but both together doesn't seem to work. The enemy acts in a weird way.
My code:
public void Start()
{
_navMeshAgent = this.GetComponent<NavMeshAgent>();
anim = GetComponent<Animator>();
if (_navMeshAgent == null)
{
Debug.LogError("not attached to " + gameObject.name);
}
else
{
if (_patrolPoints != null && _patrolPoints.Count >= 2)
{
_currentPatrolIndex = 0;
anim.SetBool("idle", true);
SetDestination();
}
else
{
Debug.Log("Insufficient patrol points.");
}
}
}
void Update()
{
if (player == null)
{
player = GameObject.Find("Player Character").GetComponent<Transform>();
}
if (Vector3.Distance(player.transform.position, this.transform.position) < 10)
{
chacePlayer();
}
else
{
patrol();
}
bool patrol()
{
Debug.Log("patrolling");
//Check if we're close to the destination.
if (_travelling && _navMeshAgent.remainingDistance <= 1.0f)
{
_travelling = false;
anim.SetBool("idle", false);
anim.SetBool("move", true);
//If we're going to wait, then wait dumbass!
if (_patrolWaiting)
{
_waiting = true;
_waitTimer = 0f;
anim.SetBool("idle", true);
anim.SetBool("move", false);
}
else
{
ChangePatrolPoint();
SetDestination();
}
}
//Instead if we're waiting...
if (_waiting)
{
_waitTimer += Time.deltaTime;
if (_waitTimer >= _totalWaitingTime)
{
_waiting = false;
anim.SetBool("move", true);
anim.SetBool("idle", false);
ChangePatrolPoint();
SetDestination();
}
}
return true;
}
}
private void SetDestination()
{
if (_patrolPoints != null)
{
Vector3 targetVector = _patrolPoints[_currentPatrolIndex].transform.position;
_navMeshAgent.SetDestination(targetVector);
_travelling = true;
////anim.SetBool("idle", false);
////anim.SetBool("move", true);
}
}
//Selects a new patrol point in the available list, but
//also with a small probability allows for us to move forward or backwards.
private void ChangePatrolPoint()
{
//Unity generate random number between 0 and 1
if (UnityEngine.Random.Range(0f, 1f) <= _switchProbability)
{
//decides if go forward or backwards: whatever the value, make the oposite
_patrolForward = !_patrolForward;
}
if (_patrolForward)
{
//if the patrolpoint exceedes patrolpoints.count, go backs to zero
_currentPatrolIndex = (_currentPatrolIndex + 1) % _patrolPoints.Count;
}
else
{
if (--_currentPatrolIndex < 0)
{
_currentPatrolIndex = _patrolPoints.Count - 1;
}
}
}
void chacePlayer()
{
Vector3 direction = player.transform.position - this.transform.position;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation,
Quaternion.LookRotation(direction), 0.1f);
direction.y = 0;
if (direction.magnitude > 2)
{
this.transform.Translate(0, 0, 0.05f);
Debug.Log("chacing");
}
}
At first I thought it was because the code was running both together so I put a Debug to see if it was that, but the debug of the patrol stops every time the enemy is following the player.
Can someone please help me?
I have some code that makes a player move up, down, left, and right.
public class playerMovement : MonoBehaviour
{
public float moveSpeed = 5f;
public Rigidbody2D rb;
public Animator animator;
public SpriteRenderer sr;
Vector2 movement;
bool walking = false;
private void Update()
{
//Inputs
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
if (Input.GetKey("left") || Input.GetKey("right") || Input.GetKey("up") || Input.GetKey("down")
{
walking = true;
}
else
{
walking = false;
}
Animate();
}
private void Animate()
{
if (Input.GetKey("down") && walking == false)
{
sr.flipX = false;
animator.Play("idle_front");
}
else if (Input.GetKey("down") && walking)
{
sr.flipX = false;
animator.Play("walk_front");
}
else if (Input.GetKey("up") && walking == false)
{
sr.flipX = false;
animator.Play("idle_back");
}
else if (Input.GetKey("down") && walking)
{
sr.flipX = false;
animator.Play("walk_back");
}
else if (Input.GetKey("left") && walking == false)
{
sr.flipX = false;
animator.Play("idle_side");
}
else if (Input.GetKey("down") && walking)
{
sr.flipX = false;
animator.Play("walk_side");
}
else if (Input.GetKey("right") && walking == false)
{
sr.flipX = true;
animator.Play("idle_side");
}
else if (Input.GetKey("right") && walking)
{
sr.flipX = true;
animator.Play("walk_side");
}
}
public void FixedUpdate()
{
//Movement
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
}
The movement is working perfectly fine, but the character just stays in it's idle state.
I have tried switching the get keys in Input.GetKey("left") || Input.GetKey("right") || Input.GetKey("up") || Input.GetKey("down") to Input.GetKeyDown() and Input.GetKeyUp(), but none of that works.
I have also tried using Blend Trees, but I cannot figure out how to do it.
I'm fairly new to Unity so a simple answer would be great.
open animator window
create 'State'
set animation clip into 'motion'
on top left click 'parameters' tab
click on plus sign next to parameters
click on 'Trigger'
name your trigger
right click on 'Any State' and make transition to drag a line to the new 'State' you created
click on the line between 'Any State' and the 'State' you created
under 'conditions' press the plus sign and add the trigger you just created
in code write
animator.SetTrigger("triggername");
when you want to transition to the before-mentioned animation state
repeat for all your animations, link them all from 'any state'
Hello i make 2D Game and implemented hover effect(floating).
first my rigidbody2D component option is blew picture.
and I made the hover function work by pressing and holding the X button.
Below is the source I created.
void Update()
{
CheckJump();
CheckRavitate();
DoingAction();
}
void DoingAction()
{
if (this.IsStatus(CustomCharacterInfo.CHAR_STATUS.JUMP))
{
// Jump
this.rigid2D.AddForce(transform.up * JUMP_FORCE);
nowStatus &= ~CustomCharacterInfo.CHAR_STATUS.JUMP;
}
if (IsStatus(CustomCharacterInfo.CHAR_STATUS.RAVITATE))
{
RaycastHit2D rayHitData = Physics2D.Raycast(
new Vector2(transform.position.x, transform.position.y),
new Vector2(0, -1.0f),0.5f,
1 << GlobalLayerMask.TERRIAN_MASK);
bool canRavitate = rayHitData.collider ? false : true;
Debug.DrawRay(transform.position, new Vector2(0, -0.8f),Color.green);
if (canRavitate)
{
float yVel = Physics.gravity.y;
Debug.Log("Ravitae FORECE " + yVel);
//Howering
rigid2D.AddForce(new Vector2(0, -yVel), ForceMode2D.Force);
}
}
}
/*
My intention is that when the x key is pressed for more than 0.05 seconds,
the floating flag is turned on.
When you release x, it will be off.
*/
void CheckRavitate()
{
if (true)
{
if (Input.GetKey(KeyCode.X))
{
if (raviValue.canRavitate && Time.time - raviValue.tDown > 0.05f && rigid2D.velocity.y < 0.2f)
{
Debug.Log("RAVITATE FLAG ON");
nowStatus |= CustomCharacterInfo.CHAR_STATUS.RAVITATE;
rigid2D.velocity = new Vector2(0.0f, 0.0f);
raviValue.canRavitate = false;
}
}
if (this.IsStatus(CustomCharacterInfo.CHAR_STATUS.RAVITATE) && Input.GetKeyUp(KeyCode.X))
{
nowStatus &= ~CustomCharacterInfo.CHAR_STATUS.RAVITATE;
raviValue.canRavitate = true;
}
}
}
void CheckJump()
{
// Jump Function
if (Input.GetKeyDown(KeyCode.X) && jumpcount > 0)
{
isGrounded = false;
nowStatus |= CustomCharacterInfo.CHAR_STATUS.JUMP;
jumpcount--;
raviValue.tDown = Time.time;
}
}
public class RavitateFlag
{
public float tDown;
public bool canRavitate;
public RavitateFlag()
{
tDown = Time.time;
canRavitate = true;
}
}
that result below that
that was errormotion capture
that was correct motion capture
The issue does not floating work with the player's computer.
I do not know why this is the difference. The code is the same and the log is the same too.
If you change one gravitiscale to 1, floating function works normally.
But I think that this is not a solution. Also, when you change the gravity scale to 1, the character that was in normal operation will fly to the sky.
I guess it is time to call the update function, but this is also not clear.
I have a canvas that is initialized when I launch the game and inside it I have a menu with the play and quit button. The game is a endless runner and everything is working fine, but when I hit the Play button to actually start the game, the Player object automatically gives me one jump, after that, it's all normal, it's like when I hit Play button it hits the game and the player too at the same time. I need this working in a Android device.
Player.cs script
...
void Start () {
Highscore = PlayerPrefs.GetInt ("Highscore", 0);
jumpOne = false;
jumpTwo = false;
canDoubleJump = false;
}
void Update() {
for (int i = 0; i < Input.touchCount; i++){
if (Input.GetTouch(i).phase == TouchPhase.Began && isFalling == false) {
jumpOne = true;
canDoubleJump = true;
isFalling = true;
}else if (Input.GetTouch(i).phase == TouchPhase.Began && isFalling == true && canDoubleJump == true) {
jumpTwo = true;
canDoubleJump = false;
}
}
}
void FixedUpdate() {
transform.Translate(Vector2.right * power * Time.deltaTime);
if (jumpOne == true) {
GetComponent<Rigidbody2D>().AddForce(Vector2.up * jumpHeight);
jumpOne = false;
}
if (jumpTwo == true) {
GetComponent<Rigidbody2D>().AddForce(Vector2.up * jumpHeight);
jumpTwo = false;
}
}
void OnCollisionStay2D(Collision2D coll) {
if (coll.gameObject.tag == "Ground") {
isFalling = false;
canDoubleJump = false;
}
}
...
//(Play Button)
public void ClickedStart() {
MainMenu.SetActive(false);
Time.timeScale = 1.0f;
Playing = true;
}
Already tried and the problem still persists
(Input.GetMouseButtonDown(0))
(Input.GetKeyDown(KeyCode.Space)) Works fine and with no bugs, but I am not able to jump running in Android.
You are using TouchPhase.Began so the moment u hide your main menu the touch is still active and hence the player jumps , I suggest you use a co-routine with waitforseconds method before you can start making the player jump again .